package com.caigou.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.caigou.bean.cms.entity.*;
import com.caigou.bean.cms.entity.SurveyFormStatistics;
import com.caigou.bean.cms.param.*;
import com.caigou.bean.exam.entity.Users;
import com.caigou.component.*;
import com.caigou.constant.NewsConstant;
import com.caigou.enums.ResponseEnum;
import com.caigou.mapper.cms.*;
import com.caigou.mapper.exam.UsersMapper;
import com.caigou.pojo.*;
import com.caigou.security.utils.CurrentUser;
import com.caigou.service.ISurveyService;
import com.caigou.service.IUserBaseInfoService;
import com.caigou.service.SurveyPermissionService;
import com.caigou.service.SurveyStatisticsService;
import com.caigou.util.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;


@Slf4j
@Service
public class SurveyServiceImpl implements ISurveyService {

    @Resource
    private RedisComponent redisComponent;
    @Resource
    private RabbitProducer rabbitProducer;
    @Resource
    private RedisObjectComponent redisObjectComponent;
    @Resource
    private CaigouIdComponent caigouIdComponent;
    @Resource
    private HttpComponent httpComponent;

    @Resource
    private IUserBaseInfoService userBaseInfoService;// 用户信息获取
    @Resource
    private SurveyPermissionService surveyPermissionService;
    @Resource
    private SurveyStatisticsService surveyStatisticsService;
    @Resource
    private ISurveyService surveyService;

    @Resource
    private SurveyFormMapper surveyFormMapper;
    @Resource
    private UserBaseInfoMapper userBaseInfoMapper;
    @Resource
    private SurveyOptionMapper surveyOptionMapper;
    @Resource
    private SurveySubmitMapper surveySubmitMapper;
    @Resource
    private SharePlatformMapper sharePlatformMapper;
    @Resource
    private SurveyCatalogMapper surveyCatalogMapper;
    @Resource
    private SurveyQuestionMapper surveyQuestionMapper;
    @Resource
    private SurveySubmitUserMapper surveySubmitUserMapper;
    @Resource
    private SurveyFormConfigMapper surveyFormConfigMapper;
    @Resource
    private SurveyFormSharePlatformMapper surveyFormSharePlatformMapper;
    @Resource
    private UsersMapper usersMapper;

    @Value("${spring.profiles.active}")
    private String activeProfile;// 当前额启动环境

    @Value("${domain}")
    private String domain;
    @Value("${mDomain}")
    private String mDomain;
    @Resource
    private OSSComponent ossComponent;

    @Value("${form.catalog.pc_url}")
    private String pcUrl;

    @Value("${form.catalog.mobile_url}")
    private String mobileUrl;

    @Value("${form.catalog.logo_path_web}")
    private String logoPathWeb;

    @Value("${form.catalog.logo_path_yct}")
    private String logoPathYct;

    @Value("${form.catalog.logo_path_yzb}")
    private String logoPathYzb;

    @Value("${form.catalog.logo_path_ykt}")
    private String logoPathYkt;

    @Value("${form.catalog.dest_path}")
    private String destPath;

    @Value("${form.catalog.domainType}")
    private Integer domainType;

    @Value("${yktappid}")
    private String yktappid;// 正福易考通微信小程序appid
    @Value("${yktappsecret}")
    private String yktappsecret;// 正福易考通微信小程序appid对应的secret

    @Value("${yzbappid}")
    private String yzbappid;// 正福易找标微信小程序appid
    @Value("${yzbappsecret}")
    private String yzbappsecret;// 正福易找标微信小程序appid对应的secret

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private QRCodeUtils qrCodeUtils;

    public SurveyForm getFormByFormId(String formId){
        return surveyFormMapper.getSurveyFormByFormId(formId);
    }

    public SurveyFormHeader getFormHeader(String formId, Integer formType, Users user){
        SurveyForm surveyForm = surveyFormMapper.getSurveyFormHeaderByFormId(formId);
        SurveyFormHeader header = new SurveyFormHeader();
        if(surveyForm==null){//表单尚未在mysql中创建
            header.setFormType(formType);
            header.setFormId(formId);
            String userId = user.getUserid();
            UserBaseInfo userBaseInfo = userBaseInfoMapper.findUserBaseInfoByUserId(userId);
            header.setPromoter(userBaseInfo.getRealName());
            header.setPromoterUserId(userId);
            header.setFormStatus(0);
            header.setFormStatusDesc("禁用");
            return header;
        }
        BeanUtil.copyProperties(surveyForm, header);
        if(surveyForm.getIsEnable()==0){//禁用
            header.setFormStatus(0);
            header.setFormStatusDesc("禁用");
        }else{
            SurveyFormConfig surveyFormConfig = surveyFormConfigMapper.getSurveyFormConfigByFormId(formId);
            if(surveyFormConfig.getEnableFormConfig().intValue()==0) {//使用目录页设置
                SurveyCatalogList surveyCatalogList = surveyCatalogMapper.selectSurveyCatalogListByFormId(formId);
                if(surveyCatalogList!=null){
                    String catalogId = surveyCatalogList.getCatalogId();
                    SurveyCatalogConfig surveyCatalogConfig = surveyCatalogMapper.loadSurveyCatalogConfig(catalogId);
                    if(surveyCatalogConfig!=null){
                        if(surveyCatalogConfig.getTimeStatus()==0){//0填表时间段设置(0长期有效1根据填写时间段计算)
                            header.setFormStatus(1);
                            header.setFormStatusDesc("进行中");
                        }else{//1(0长期有效1根据填写时间段计算)
                            Date startTime = surveyCatalogConfig.getStartTime();
                            Date endTime = surveyCatalogConfig.getEndTime();
                            Date currentTime = new Date(System.currentTimeMillis());
                            if(startTime==null || endTime==null){
                                header.setFormStatus(2);
                                header.setFormStatusDesc("未开始");
                            }else{
                                if(currentTime.getTime()<startTime.getTime()){
                                    header.setFormStatus(2);
                                    header.setFormStatusDesc("未开始");
                                }else if(currentTime.getTime()>endTime.getTime()){
                                    header.setFormStatus(3);
                                    header.setFormStatusDesc("已过期");
                                }else{
                                    header.setFormStatus(1);
                                    header.setFormStatusDesc("进行中");
                                }
                            }
                        }
                    }
                }
            }else{
                if(surveyFormConfig.getEnableTimeRestriction().intValue()==0){//时间无限制
                    header.setFormStatus(1);
                    header.setFormStatusDesc("进行中");
                }else{
                    Date startTime = surveyFormConfig.getStartTime();
                    Date endTime = surveyFormConfig.getEndTime();
                    Date currentTime = new Date(System.currentTimeMillis());
                    if(startTime==null || endTime==null){
                        header.setFormStatus(2);
                        header.setFormStatusDesc("未开始");
                    }else{
                        if(currentTime.getTime()<startTime.getTime()){
                            header.setFormStatus(2);
                            header.setFormStatusDesc("未开始");
                        }else if(currentTime.getTime()>endTime.getTime()){
                            header.setFormStatus(3);
                            header.setFormStatusDesc("已过期");
                        }else{
                            header.setFormStatus(1);
                            header.setFormStatusDesc("进行中");
                        }
                    }
                }
            }
        }
        return header;

    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result removeFormInCatalog(String catalogId, String formId){
        //1获取SurveyCatalogList
        SurveyCatalogList surveyCatalogList = surveyCatalogMapper.selectSurveyCatalogList(catalogId, formId);
        if(surveyCatalogList==null){
            return Result.error("表单目录页关联表中无此记录", "表单目录页关联表中无此记录");
        }
        //2删除该数据
        int result = surveyCatalogMapper.deleteSurveyCatalogListByFormId(formId);
        if(result>0){
            //3将表单surveyForm的enableFormConfig设置为1
            SurveyFormConfig surveyFormConfig = new SurveyFormConfig();
            surveyFormConfig.setFormId(formId);
            surveyFormConfig.setEnableFormConfig(1);
            surveyFormConfig.setUpdateTime(new Date(System.currentTimeMillis()));
            int result0 = surveyFormConfigMapper.updateByFormIdSelective(surveyFormConfig);
            //4调整showIndex值
            int result1 = surveyCatalogMapper.updateShowIndex(surveyCatalogList);
            redisComponent.del("formCatalog:"+formId);// 清除表单目录的关联状态
            redisComponent.del("formResult:"+formId);// 清除表单目录的关联状态
            redisComponent.del("catalogResult:"+surveyCatalogList.getCatalogId());// 清除表单目录的关联状态
            return Result.success("删除表单目录页关联关系成功");
        }else {
            return Result.error("删除表单目录页关联关系失败", "删除表单目录页关联关系失败");
        }
    }

    public Result updateIsEnableByFormId(SurveyFormParam param, Users user){
        String formId = param.getFormId();
        SurveyForm surveyForm = surveyFormMapper.getSurveyFormByFormId(formId);
        if(surveyForm==null){
            return Result.error("没有这个表单，不能进行启用/禁用操作");
        }
        SurveyFormConfig surveyFormConfig = surveyFormConfigMapper.getSurveyFormConfigByFormId(formId);
        if(surveyFormConfig==null){
            return Result.error("没有这个表单设置，不能进行启用/禁用操作");
        }
        if(param.getIsEnable().intValue()==1 && surveyFormConfig.getEnableTimeRestriction().intValue()==1){//启用操作 而且表单设置时间限制
            if(surveyFormConfig.getCreateTime()==null || surveyFormConfig.getEndTime()==null){//开始时间、结束时间没有填写
                return Result.error("表单尚未设置开始、结束时间，不能启用", "表单尚未设置开始、结束时间，不能启动");
            }
        }

        //清除redis中form:formId缓存
        String key = "form:"+formId;
        Boolean flag = redisObjectComponent.del(key);
        log.info("清除表单缓存，delete key={} from redis result={}", key, flag);

        //清除formResult的缓存：redis中formResult:formId缓存
        String key2 = "formResult:"+formId;
        Boolean flag2 = redisObjectComponent.del(key2);
        log.info("清除formResult缓存，delete key={} from redis result={}", key2, flag2);

        if(param.getIsEnable().intValue()==0){//禁用

            //TODO 清除redis中该表单的目录页数据
            SurveyCatalogList surveyCatalogList = surveyCatalogMapper.selectSurveyCatalogListByFormId(formId);
            if(surveyCatalogList!=null){
                String catalogId = surveyCatalogList.getCatalogId();
                if(catalogId!=null) {
                    String key3 = "catalogResult:" + catalogId;
                    Boolean flag3 = redisObjectComponent.del(key3);
                    log.info("清除catalogResult缓存，delete key={} from redis result={}", key3, flag3);
                }
            }
        }

        surveyForm.setIsEnable(param.getIsEnable());
        surveyForm.setUpdateTime(new Date(System.currentTimeMillis()));
        int result = surveyFormMapper.updateIsEnableByFormId(surveyForm);
        if(result>0){
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getFormId());
            operationLog.setDataType(1);
            operationLog.setUserId(user.getUserid());
            if(param.getIsEnable().intValue()==1) {
                operationLog.setActionType(3);
                operationLog.setActionName("启用表单");
            }else{
                operationLog.setActionType(4);
                operationLog.setActionName("禁用表单");
            }
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
            return Result.success("更新表单启用/停用状态成功");
        }else {
            return Result.error("更新表单启用/停用状态失败", "更新表单启用/停用状态失败");
        }
    }

    public Result deleteFormByFormId(SurveyFormParam param, Users user){
        SurveyForm surveyForm = this.getFormByFormId(param.getFormId());
        if(surveyForm==null){
            return Result.error("没有这个表单，不能删除", "没有这个表单，不能删除");
        }
        if(surveyForm.getIsEnable().intValue()!=0){
            return Result.error("表单不是禁用状态，不能删除", "表单不是禁用状态，不能删除");
        }

        //清除redis中form:formId缓存
        String key = "form:"+param.getFormId();
        Boolean flag = redisObjectComponent.del(key);
        log.info("清除表单缓存，delete key={} from redis result={}", key, flag);

        //清除formResult的缓存：redis中formResult:formId缓存
        String key2 = "formResult:"+param.getFormId();
        Boolean flag2 = redisObjectComponent.del(key2);
        log.info("清除formResult缓存，delete key={} from redis result={}", key2, flag2);

        //TODO 清除redis中该表单的目录页数据
        SurveyCatalogList surveyCatalogList = surveyCatalogMapper.selectSurveyCatalogListByFormId(param.getFormId());
        if(surveyCatalogList!=null){
            String catalogId = surveyCatalogList.getCatalogId();
            if(catalogId!=null) {
                String key3 = "catalogResult:" + catalogId;
                Boolean flag3 = redisObjectComponent.del(key3);
                log.info("清除catalogResult缓存，delete key={} from redis result={}", key3, flag3);
            }
        }


        //首先删除表单-目录关联表中的数据
        int result0 = surveyCatalogMapper.deleteByFormId(param.getFormId());
        //其次逻辑删除表单
        surveyForm.setIsDelete(1);
        surveyForm.setUpdateTime(new Date(System.currentTimeMillis()));
        surveyForm.setDeleteTime(new Date(System.currentTimeMillis()));
        int result = surveyFormMapper.updateIsDeleteByFormId(surveyForm);
        if(result>0){
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getFormId());
            operationLog.setDataType(1);
            operationLog.setUserId(user.getUserid());
            operationLog.setActionType(5);
            operationLog.setActionName("删除表单到回收站");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);

            return Result.success("删除表单成功");
        }else{
            return Result.error("删除表单失败", "删除表单失败");
        }
    }

    public SurveyForm getPreFormByFormType(Integer formType, Users user){
        SurveyForm surveyForm = new SurveyForm();
        Long caigouId = caigouIdComponent.getCaigouIdCompnent();
        String formId = String.valueOf(caigouId);
        surveyForm.setFormId(formId);
        surveyForm.setFormType(formType);
        String userId = user.getUserid();
        surveyForm.setPromoterUserid(user.getUserid());
        UserBaseInfo userBaseInfo = userBaseInfoMapper.findUserBaseInfoByUserId(userId);
        surveyForm.setPromoter(userBaseInfo.getRealName());
        return surveyForm;
    }

    public SurveyFormConfig getSimpleSurveyFormConfigByFormId(String formId){
        SurveyFormConfig surveyFormConfig = surveyFormConfigMapper.getSurveyFormConfigByFormId(formId);
        return surveyFormConfig;
    }

    public SurveyFormConfig getSurveyFormConfigByFormId(String formId){
        SurveyFormConfig surveyFormConfig = surveyFormConfigMapper.getSurveyFormConfigByFormId(formId);
        List<SurveyFormSharePlatform> surveyFormSharePlatforms = surveyFormSharePlatformMapper.selectByFormId(formId);

        SurveyForm surveyForm = surveyFormMapper.getSurveyFormByFormId(formId);
        int questionCount = surveyQuestionMapper.getQuestionCountByFormId(formId);

        //1如果表单设置了时间限制，但是没有设置开始时间、结束时间;2没有该表单；3表单没有标题；4表单内的题目数量为0；则设置surveyFormSharePlatform的链接和二维码
        if((surveyFormConfig.getEnableTimeRestriction()==1 && (surveyFormConfig.getStartTime()==null||surveyFormConfig.getEnableTimeRestriction()==null))
            ||surveyForm==null || surveyForm.getFormTitle()==null || questionCount==0){
            for(SurveyFormSharePlatform surveyFormSharePlatform:surveyFormSharePlatforms){
                surveyFormSharePlatform.setUrl(null);
                surveyFormSharePlatform.setQrCode(null);
            }
        }

        for(int i=1; i<surveyFormSharePlatforms.size(); i=i+2){
            SurveyFormSharePlatform surveyFormSharePlatform = surveyFormSharePlatforms.get(i);
            surveyFormSharePlatform.setEnableRecommend(0);
        }
        surveyFormConfig.setSurveyFormSharePlatformList(surveyFormSharePlatforms);
        return surveyFormConfig;
    }

    public int createSurveyFormConfig(SurveyFormConfigParam param){
        SurveyFormConfig surveyFormConfig = new SurveyFormConfig();
        BeanUtil.copyProperties(param, surveyFormConfig);
        int result = surveyFormConfigMapper.insertSelective(surveyFormConfig);
        return result;
    }

    public int createDefaultSurveyFormConfig(String formId){
        SurveyFormConfig surveyFormConfig = new SurveyFormConfig();
        surveyFormConfig.setFormId(formId);
        surveyFormConfig.setEnableTimeRestriction(1);//表单填写时间限制，0不限制，1限制
        surveyFormConfig.setBeforeStartTip("您所访问的表单还未开放");
        surveyFormConfig.setAfterEndTip("您所访问的表单收集已结束");
        return surveyFormConfigMapper.insertSelective(surveyFormConfig);
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public int createOrUpdateSurveyFormConfig(SurveyFormConfigParam param, Users user){
        SurveyFormConfig surveyFormConfig = surveyFormConfigMapper.getSurveyFormConfigByFormId(param.getFormId());
        if(surveyFormConfig==null){//create增加
            int result1 = this.createSurveyFormConfig(param);
            int result2 = this.batchCreateSurveyFormSharePlatform(param.getFormId());
            return result1+result2;
        }else{//update更新
            //清除redis中formConfig:formId缓存
            String key = "formConfig:"+param.getFormId();
            Boolean flag = redisObjectComponent.del(key);
            log.info("清除表单设置缓存，delete key={} from redis result={}", key, flag);

            redisObjectComponent.del("formResult:"+param.getFormId());

            SurveyFormConfig newSurveyFormConfig = new SurveyFormConfig();
            BeanUtil.copyProperties(param, newSurveyFormConfig);
            int result = surveyFormConfigMapper.updateByFormIdSelective(newSurveyFormConfig);
            if(result>0){
                SurveyOperationLog operationLog = new SurveyOperationLog();
                operationLog.setDataId(param.getFormId());
                operationLog.setDataType(1);
                operationLog.setUserId(user.getUserid());
                operationLog.setActionType(2);
                operationLog.setActionName("修改表单设置");
                surveyCatalogMapper.saveSurveyOperationLog(operationLog);
            }
            SurveyFormConfig formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            redisObjectComponent.set("formConfig:"+param.getFormId(),formConfig);
            // 清除当前目录下所有用户的权限
            if (null != param.getEnableFormConfig() && null != param.getVerifyType() && null != param.getEnableInvite()){
                if (param.getEnableFormConfig() == 1 &&
                        (param.getVerifyType() == 0 || param.getEnableInvite() == 1) &&
                        (!surveyFormConfig.getVerifyType().equals(param.getVerifyType()) || !surveyFormConfig.getEnableInvite().equals(param.getEnableInvite()))){
                    log.info("目录下所有表单使用此设置，并且登录状态判定/邀请码判定有修改，进行用户权限清除");
                    surveyPermissionService.deletePermissionByForm(param.getFormId());
                    redisComponent.del("formPermission:"+param.getFormId());
                }
            }
            return result;
        }
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public int updateSurveyFormSharePlatform(SurveyFormShardPlatformListParam param){
        List<SurveyFormSharePlatformParam> paramList = param.getSurveyFormSharePlatformList();
        List<SurveyFormSharePlatform> list = new ArrayList<SurveyFormSharePlatform>(paramList.size());
        for(int i=0; i<paramList.size()-1; i=i+2){
            //偶数--pc端
            SurveyFormSharePlatformParam evenItem = paramList.get(i);
            SurveyFormSharePlatform evenSurveyFormSharePlatform = new SurveyFormSharePlatform();
            BeanUtil.copyProperties(evenItem, evenSurveyFormSharePlatform);
            evenSurveyFormSharePlatform.setUpdateTime(new Date(System.currentTimeMillis()));
            //如果分享平台是易考通或者易找标，需要重新生成qrCode
            if(evenItem.getPlatformId().intValue()==3){//分享平台是易找标
                String yzbMiniUrl = "pages/mainPackage/index/index?formId="+param.getFormId()+"&platform=4&source=4&domain="+domainType;
                String qrCode = this.getYzbMiniQrCode(yzbMiniUrl, param.getFormId(), null);
                evenSurveyFormSharePlatform.setQrCode(qrCode);
            }else if(evenItem.getPlatformId().intValue()==4){//分享平台是易考通
                String yktMiniUrl = "pages/homePage/homePage?formId="+param.getFormId()+"&platform=4&source=3&domain="+domainType;
                String qrCode = this.getYktMiniQrCode(yktMiniUrl, param.getFormId(), null);
                evenSurveyFormSharePlatform.setQrCode(qrCode);
            }
            list.add(evenSurveyFormSharePlatform);
            //奇数--移动端
            SurveyFormSharePlatformParam oddItem = paramList.get(i+1);
            SurveyFormSharePlatform oddSurveyFormSharePlatform = new SurveyFormSharePlatform();
            BeanUtil.copyProperties(oddItem, oddSurveyFormSharePlatform);

            //使用偶数位置的数据更新奇数位置的数据--是否推荐及推荐提示
            oddSurveyFormSharePlatform.setEnableRecommend(evenItem.getEnableRecommend());
            oddSurveyFormSharePlatform.setRecommendTip(evenItem.getRecommendTip());

            oddSurveyFormSharePlatform.setUpdateTime(new Date(System.currentTimeMillis()));

            //如果分享平台是易考通或者易找标，需要重新生成qrCode
            if(oddItem.getPlatformId().intValue()==3){//分享平台是易找标
                String yzbMiniUrl = "pages/mainPackage/index/index?formId="+param.getFormId()+"&platform=4&source=4&domain="+domainType;
                String qrCode = this.getYzbMiniQrCode(yzbMiniUrl, param.getFormId(), null);
                oddSurveyFormSharePlatform.setQrCode(qrCode);
            }else if(oddItem.getPlatformId().intValue()==4){//分享平台是易考通
                String yktMiniUrl = "pages/homePage/homePage?formId="+param.getFormId()+"&platform=4&source=3&domain="+domainType;
                String qrCode = this.getYktMiniQrCode(yktMiniUrl, param.getFormId(), null);
                oddSurveyFormSharePlatform.setQrCode(qrCode);
            }

            list.add(oddSurveyFormSharePlatform);
        }
        int result = surveyFormSharePlatformMapper.batchUpdateSurveyFormSharePlatform(list);
        redisObjectComponent.del("formResult:"+param.getFormId());
        return result;
    }


    public int batchCreateSurveyFormSharePlatform(String formId){
        //获取分享平台list
        List<SharePlatform> platformList = sharePlatformMapper.listAllSharePlatform();
        int size = platformList.size();
        List<SurveyFormSharePlatform> list = new ArrayList<SurveyFormSharePlatform>(size*2);

        for(SharePlatform sharePlatform:platformList){
            //pc端关联对象，terminal=0
            SurveyFormSharePlatform surveyFormSharePlatform = this.buildSurveyFormSharePlatform(sharePlatform, formId, 0);
            //移动端关联对象，terminal=1
            SurveyFormSharePlatform surveyFormSharePlatform2= this.buildSurveyFormSharePlatform(sharePlatform, formId, 1);

            //用移动端的二维码url设置pc端的二维码
            surveyFormSharePlatform.setQrCode(surveyFormSharePlatform2.getQrCode());

            list.add(surveyFormSharePlatform);
            list.add(surveyFormSharePlatform2);
        }

        return surveyFormSharePlatformMapper.batchCreateSurveyFormSharePlatform(list);
    }

    public PageInfo<SurveyForm> queryForm(QueryFormParam param){
        Page<?> page = PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<SurveyForm> formList = surveyFormMapper.queryForm(param);
        for(SurveyForm surveyForm:formList){
            String formId = surveyForm.getFormId();
            List<SurveyFormSharePlatform> surveyFormSharePlatformList = surveyFormSharePlatformMapper.selectRecommendByFormId(formId);
            List<SharePlatform> sharePlatformList = new ArrayList<>(surveyFormSharePlatformList.size());
            for(SurveyFormSharePlatform surveyFormSharePlatform:surveyFormSharePlatformList){
                sharePlatformList.add(surveyFormSharePlatform.getSharePlatform());
            }
            //根据共享平台的名称去重
            List<SharePlatform> uniquePlatformList = sharePlatformList.stream().collect(
                    collectingAndThen(
                            Collectors.toCollection(() -> new TreeSet<>((Comparator.comparing(o-> o.getPlatformName())))), ArrayList::new)
            );
            surveyForm.setSharePlatformList(uniquePlatformList);
            SurveyFormConfig surveyFormConfig = surveyForm.getSurveyFormConfig();
            if(surveyFormConfig!=null){//判断是否使用目录页设置
                if(surveyFormConfig.getEnableFormConfig()==0){//使用目录页设置
                    SurveyCatalogList surveyCatalogList = surveyCatalogMapper.selectSurveyCatalogListByFormId(formId);
                    if(surveyCatalogList!=null){
                        String catalogId = surveyCatalogList.getCatalogId();
                        SurveyCatalogConfig surveyCatalogConfig = surveyCatalogMapper.loadSurveyCatalogConfig(catalogId);
                        if(surveyCatalogConfig!=null){
                            surveyFormConfig.setEnableTimeRestriction(-1);//前端显示：按目录页设置
                        }
                    }
                }
            }
        }
        PageInfo<SurveyForm> formPageInfo = new PageInfo<>(formList);
        return formPageInfo;
    }

    /**
     * 为目录页查询表单
     * @param param
     * @return
     */
    public PageInfo<SurveyForm> queryForm4Catalog(QueryFormParam param){
        Page<?> page = PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<SurveyForm> formList = surveyFormMapper.queryForm4Catalog(param);
        PageInfo<SurveyForm> formPageInfo = new PageInfo<>(formList);
        return formPageInfo;
    }


    /**
     * 创建智能表单
     * @param param
     * @param user
     * @return
     */
    public int createSurveyForm(SurveyFormParam param, Users user){
        SurveyForm surveyForm = new SurveyForm();
        BeanUtil.copyProperties(param, surveyForm);
        surveyForm.setIsEnable(0);
        String userId = user.getUserid();
        surveyForm.setPromoterUserid(userId);
        UserBaseInfo userBaseInfo = userBaseInfoMapper.findUserBaseInfoByUserId(userId);
        surveyForm.setPromoter(userBaseInfo.getRealName());
        Date currentTime = new Date(System.currentTimeMillis());
        surveyForm.setCreateTime(currentTime);
        surveyForm.setUpdateTime(currentTime);
        int result = surveyFormMapper.insertSelective(surveyForm);
        this.createDefaultSurveyFormConfig(param.getFormId());
        this.batchCreateSurveyFormSharePlatform(param.getFormId());
        if(result>0){
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getFormId());
            operationLog.setDataType(1);
            operationLog.setUserId(user.getUserid());
            operationLog.setActionType(1);
            operationLog.setActionName("创建表单");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        }

        return result;
    }

    /**
     * 更新智能表单
     * @param param
     * @return
     */
    public int updateSurveyForm(SurveyFormParam param, Users user){

        //清除redis中form:formId缓存
        String key = "form:"+param.getFormId();
        Boolean flag = redisObjectComponent.del(key);
        log.info("清除表单缓存，delete key={} from redis result={}", key, flag);

        SurveyForm surveyForm = new SurveyForm();
        BeanUtil.copyProperties(param, surveyForm);
        surveyForm.setUpdateTime(new Date(System.currentTimeMillis()));
        int result = surveyFormMapper.updateByFormIdSelective(surveyForm);
        if(result>0){
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getFormId());
            operationLog.setDataType(1);
            operationLog.setUserId(user.getUserid());
            operationLog.setActionType(2);
            operationLog.setActionName("修改表单");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);

        }
        return result;
    }

    /**
     * 创建或者更新智能表单
     * @param param
     * @param user
     * @return
     */
    public int createOrUpdateSurveyForm(SurveyFormParam param, Users user){
        String formId = param.getFormId();
        SurveyForm surveyForm = getFormByFormId(formId);
        int result = 0;
        if(surveyForm==null){//surveyForm为空时，意味着是创建新的表单
            result = createSurveyForm(param, user);
            String key = NewsConstant.CREATE_FORM_PRE_KEY+formId;
            redisComponent.set(key,"1");
            return result;
        }else{//surveyForm不是空时，修改表单
            //清除redis中form:formId缓存
            String redisKey = "form:"+formId;
            Boolean flag = redisObjectComponent.del(redisKey);
            log.info("清除缓存缓存，delete key={} from redis result={}", redisKey, flag);

            // 清除formResult缓存
            redisObjectComponent.del("formResult:"+formId);

            result = updateSurveyForm(param, user);
            String key = NewsConstant.CREATE_FORM_PRE_KEY+formId;
            redisComponent.set(key, "0");
            return result;
        }

    }



    /**
     * 构造SurveyFormSharePlatform对象
     * @param sharePlatform
     * @param formId
     * @param terminal
     * @return
     */
    private SurveyFormSharePlatform buildSurveyFormSharePlatform(SharePlatform sharePlatform, String formId, int terminal){
        if(terminal!=0 && terminal!=1){
            log.error("SurveyFormSharePlatform对象失败，terminal类型值错误,terminal={}", terminal);
            return null;
        }
        SurveyFormSharePlatform surveyFormSharePlatform = new SurveyFormSharePlatform();
        surveyFormSharePlatform.setFormId(formId);
        surveyFormSharePlatform.setPlatformId(sharePlatform.getId());
        surveyFormSharePlatform.setTerminal(terminal);//0电脑端,1移动端
        //platform 设备平台1PC、2安卓、3IOS、4、移动、5微信
        //source 来源 1政府采购信息网、2易采通app3、正福易考通、4正福易找标、5微信公众号
        String url = null;
        String yktMiniUrl = "pages/homePage/homePage";//易考通微信小程序码对应的页面url
        String yzbMiniUrl = "pages/mainPackage/index/index";//易找标微信小程序码对应的页面url
        if(terminal==1){//移动端
            url = mobileUrl+"?formId="+formId+"&platform=4";
            yktMiniUrl = yktMiniUrl+"?formId="+formId+"&platform=4";
            yzbMiniUrl = yzbMiniUrl+"?formId="+formId+"&platform=4";
        }else {//pc端
            url = pcUrl+"?formId="+formId+"&platform=1";
            yktMiniUrl = yktMiniUrl+"?formId="+formId+"&platform=1";
            yzbMiniUrl = yzbMiniUrl+"?formId="+formId+"&platform=1";
        }
        surveyFormSharePlatform.setEnableRecommend(0);//是否推荐二维码
        surveyFormSharePlatform.setRecommendTip("");//二维码推荐语
        if(sharePlatform.getPlatformName().equals("政府采购信息网&微信公众号")){
            surveyFormSharePlatform.setGotoName("稿件库");
            surveyFormSharePlatform.setGotoUrl("https://admin.caigou2003.com/#/gaojiankuzhuanti");
            url = url + "&source=1";
        }else if(sharePlatform.getPlatformName().equals("易采通App")){
            surveyFormSharePlatform.setGotoName("易采通app后台");
            surveyFormSharePlatform.setGotoUrl("https://v1.caigou2003.com/cms_web");
            url = url + "&source=2";
        }else if(sharePlatform.getPlatformName().equals("正福易找标")){
            surveyFormSharePlatform.setGotoName("正福易找标后台");
            surveyFormSharePlatform.setGotoUrl("https://bid.caigou2003.com");
            url = url + "&source=4";
            yzbMiniUrl = yzbMiniUrl + "&source=4";
        }else if(sharePlatform.getPlatformName().equals("正福易考通")){
            surveyFormSharePlatform.setGotoName("正福易考通后台");
            surveyFormSharePlatform.setGotoUrl("https://user.caigou2003.com/admin/bm/index");
            url = url + "&source=3";
            yktMiniUrl = yktMiniUrl + "&source=3";
        }else{
            surveyFormSharePlatform.setGotoName("");
            surveyFormSharePlatform.setGotoUrl("");
        }
        surveyFormSharePlatform.setUrl(url);//链接地址
        //表单二维码
        String qrCodeUrl = null;
        if(terminal==1){//移动端才有二维码
            try{
                if(sharePlatform.getPlatformName().equals("政府采购信息网&微信公众号")){//官网或微信公众号平台
                    qrCodeUrl = qrCodeUtils.encode(url,logoPathWeb,destPath,"web-form-"+formId,true);
                }else if(sharePlatform.getPlatformName().equals("易采通App")){//易采通平台
                    qrCodeUrl = qrCodeUtils.encode(url,logoPathYct,destPath,"yct-form-"+formId,true);
                }else if(sharePlatform.getPlatformName().equals("正福易找标")){//易找标平台
                    //易找标微信小程序二维码
                    yzbMiniUrl = yzbMiniUrl+"&domain="+domainType;
                    log.info("yzbMiniUrl={}, formId={}", yzbMiniUrl, formId);
                    qrCodeUrl = getYzbMiniQrCode(yzbMiniUrl, formId, null);
                }else if(sharePlatform.getPlatformName().equals("正福易考通")){//易考通平台
                    //易考通微信小程序二维码
                    yktMiniUrl = yktMiniUrl+"&domain="+domainType;
                    log.info("yktMiniUrl={}, formId={}", yktMiniUrl, formId);
                    qrCodeUrl = getYktMiniQrCode(yktMiniUrl, formId, null);
                }
                if(qrCodeUrl==null){
                    qrCodeUrl = "";
                }
                log.info("分享平台的二维码qrCodeUrl={}", qrCodeUrl);
                surveyFormSharePlatform.setQrCode(qrCodeUrl);//二维码
            }catch(Exception e){
                log.error(e.getMessage(), e);
            }
        }else {
            surveyFormSharePlatform.setQrCode("");//二维码
        }

        Date currentTime = new Date(System.currentTimeMillis());
        surveyFormSharePlatform.setCreateTime(currentTime);
        surveyFormSharePlatform.setUpdateTime(currentTime);
        surveyFormSharePlatform.setRecommendTip("微信扫一扫");
        return surveyFormSharePlatform;
    }


    /**
     * 获取易考通小程序中智能表单的小程序码
     * @param path:易考通小程序页面path
     * @param formId
     * @param catalogId
     * @return
     */
    public String getYktMiniQrCode(String path, String formId, String catalogId){
        String accessToken = getYktWeixinAccessToken();
        String qrCodeUrl = getMiniQrCode(accessToken, path, formId, catalogId, "ykt");
        return qrCodeUrl;
    }

    /**
     * 获取易找标小程序中智能表单的小程序码
     * @param path:易找标小程序页面path
     * @param formId
     * @param catalogId
     * @return
     */
    public String getYzbMiniQrCode(String path, String formId, String catalogId){
        String accessToken = getYzbWeixinAccessToken();
        String qrCodeUrl = getMiniQrCode(accessToken, path, formId, catalogId, "yzb");
        return qrCodeUrl;
    }


    /**
     *
     * @param accessToken
     * @param path
     * @param formId
     * @param catalogId
     * @param type 取值为ykt或者yzb等
     * @return
     */
    private String getMiniQrCode(String accessToken, String path, String formId, String catalogId, String type){
        String qrCodeUrl = null;
        InputStream inputStream = null;
        try{
            //采用接口A方式获取小程序码
            String wxaUrl = "https://api.weixin.qq.com/wxa/getwxacode?access_token="+accessToken;//https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accessToken;//获取小程序码的api接口
            Map<String, Object> param = new HashMap<>();
            param.put("path", path);
            log.info("调用生成微信小程序码的URL接口传参:"+param);
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            HttpEntity requestEntity = new HttpEntity(JSON.toJSONString(param), headers);
            ResponseEntity<byte[]> entity = restTemplate.exchange(wxaUrl, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            byte[] result = entity.getBody();
            inputStream = new ByteArrayInputStream(result);
            if(!StringUtils.isEmpty(formId)){
                qrCodeUrl = ossComponent.uploadToOSSWithFileName(inputStream, type+"-form-"+formId+".png", "qrCodeImage/");
            }else{
                qrCodeUrl = ossComponent.uploadToOSSWithFileName(inputStream, type+"-catalog-"+catalogId+".png", "qrCodeImage/");
            }
            if(qrCodeUrl!=null){
                log.info("智能表单小程序码qrCodeUtl={}", qrCodeUrl);
            }
        }catch(Exception e){
            log.error(e.getMessage(), e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return qrCodeUrl;
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result createOrUpdateQuestionAndOption(QuestionAndOptionParam param){
        int result = 0;
        QuestionParam questionParam = param.getQuestionParam();
        OptionParam optionParam = param.getOptionParam();

        //清除formResult的缓存：redis中formResult:formId缓存
        String key = "formResult:"+questionParam.getFormId();
        Boolean flag = redisObjectComponent.del(key);
        log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);

        //清除formQuestion的缓存：redis中formQuestion:formId缓存
        String key2 = "formQuestion:"+questionParam.getQuestionId();
        Boolean flag2 = redisObjectComponent.del(key2);
        log.info("清除题目缓存，delete key={} from redis result={}", key2, flag2);



        List<Option> options = null;
        if(optionParam!=null){
            options = optionParam.getOptions();
        }
        Integer questionId = questionParam.getQuestionId();
        SurveyQuestion surveyQuestion = this.buildSurveyQuestion(questionParam);

        int result0 = 0;//创建/修改题目的结果
        if(questionId==null){//创建题目
            //判断新创建的这个题目是否大于目前数据库表中最大的questionOrder，是：直接保存新创建的题目；否：先更新原有大于该questionOrder的题目的为questionOrder+1
            Integer maxQuestionOrder = surveyQuestionMapper.getMaxOrderByFormId(questionParam.getFormId());
            if(maxQuestionOrder==null){
                maxQuestionOrder = 0;
            }
            if(questionParam.getQuestionOrder()==null){
                return Result.error("缺少题目组件序号", "缺少题目组件序号");
            }
            if(questionParam.getQuestionOrder()<1 || questionParam.getQuestionOrder().intValue()>maxQuestionOrder+1){
                log.error("题目序号错误questionOrder={}, maxQuestionOrder={}", questionParam.getQuestionOrder(), maxQuestionOrder);
                return Result.error("请先保存之前的题目组件", "请先保存之前的题目组件");
                //return Result.error("题目序号参数错误", "题目序号参数错误");
            }
            surveyQuestion.setQuestionOrder(maxQuestionOrder+1);
            //先保存题目
            result0 = surveyQuestionMapper.insertSelective(surveyQuestion);
            log.info("创建题目questionId={},title={}的结果{}", surveyQuestion.getId(), surveyQuestion.getQuestionTitle(), result0);
            //再移动题目
            if(questionParam.getQuestionOrder().intValue()<=maxQuestionOrder){
                log.info("移动题目questionId={}， from={} to={}", surveyQuestion.getId(), surveyQuestion.getQuestionOrder(), questionParam.getQuestionOrder());
                MoveQuestionParam moveQuestionParam = new MoveQuestionParam();
                moveQuestionParam.setFormId(questionParam.getFormId());
                moveQuestionParam.setQuestionId(surveyQuestion.getId());
                moveQuestionParam.setToOrder(questionParam.getQuestionOrder());
                this.moveQuestion(moveQuestionParam);
            }
        }else{
            //修改题目
            surveyQuestion.setCreateTime(null);
            surveyQuestion.setQuestionOrder(null);//暂时不修改questionOrder
            surveyQuestion.setId(questionId);
            result0 = surveyQuestionMapper.updateByPrimaryKeySelective(surveyQuestion);
            log.info("修改题目questionId={},title={}的结果{}", surveyQuestion.getId(), surveyQuestion.getQuestionTitle(), result0);
            //再移动题目
            MoveQuestionParam moveQuestionParam = new MoveQuestionParam();
            moveQuestionParam.setQuestionId(surveyQuestion.getId());
            moveQuestionParam.setToOrder(param.getQuestionParam().getQuestionOrder());
            log.info("开始移动题目{}到{}", surveyQuestion.getId(), param.getQuestionParam().getQuestionOrder());
            this.moveQuestion(moveQuestionParam);
            log.info("结束移动题目{}到{}", surveyQuestion.getId(), param.getQuestionParam().getQuestionOrder());
            // 清除题目缓存
            String key3 = "formQuestion:"+questionId;
            Boolean flag3 = redisObjectComponent.del(key3);
            log.info("清除选项缓存，delete key={} from redis result={}", key3, flag3);
        }
        result+=result0;
        //创建或者保存题目选项（包括移动）
        if(options!=null){
            for(Option option:options){
                Integer optionId = option.getOptionId();
                SurveyOption surveyOption = this.buildSurveyOption(option, surveyQuestion);
                int result1 = 0;//创建、修改单个选项的结果
                if(optionId==null){//创建选项
                    Integer maxOrder = surveyOptionMapper.getMaxOrderByQuestionId(surveyQuestion.getId());
                    if(maxOrder==null){
                        maxOrder=0;
                    }
                    surveyOption.setOptionOrder(maxOrder+1);
                    result1 = surveyOptionMapper.insertSelective(surveyOption);
                    log.info("创建题目选项id={}, title={}, 结果={}", surveyOption.getId(), surveyOption.getOptionTitle(), result1);
                }else{//修改选项
                    //清除formOption的缓存：redis中formOption:optionId缓存
                    String key3 = "formOption:"+optionId;
                    Boolean flag3 = redisObjectComponent.del(key3);
                    log.info("清除选项缓存，delete key={} from redis result={}", key3, flag3);

                    surveyOption.setCreateTime(null);
                    surveyOption.setOptionOrder(null);//不调整选项序号
                    surveyOption.setId(optionId);
                    result1 = surveyOptionMapper.updateByPrimaryKeySelective(surveyOption);
                    log.info("更新题目选项id={}, title={}, 结果={}", surveyOption.getId(), surveyOption.getOptionTitle(), result1);
                }
                result+=result1;
            }
        }
        if(result>0){
            surveyQuestion = surveyQuestionMapper.selectByPrimaryKey(surveyQuestion.getId());
            QuestionAndOptionParam questionAndOptionParam = this.getQuestionAndOption(surveyQuestion);
            return Result.success(questionAndOptionParam);
            //return Result.success(surveyQuestion);
        }else{
            return Result.error("保存题目及选项失败", "保存题目及选项失败");
        }
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public int deleteQuestionAndOption(QuestionParam param){
        SurveyQuestion surveyQuestion = surveyQuestionMapper.selectByPrimaryKey(param.getQuestionId());
        if(surveyQuestion==null){
            return 0;
        }

        //清除formResult的缓存：redis中formResult:formId缓存
        String key = "formResult:"+surveyQuestion.getFormId();
        Boolean flag = redisObjectComponent.del(key);
        log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);

        //清除formQuestion的缓存：redis中formQuestion:questionId缓存
        String key2 = "formQuestion:"+surveyQuestion.getId();
        Boolean flag2 = redisObjectComponent.del(key2);
        log.info("清除题目缓存，delete key={} from redis result={}", key2, flag2);

        //清除formOption的缓存，redis中formOption:optionId
        List<SurveyOption> options = surveyOptionMapper.selectByQuestionId(surveyQuestion.getId());
        for(SurveyOption option:options){
            //清除formOption的缓存：redis中formOption:optionId缓存
            String key3 = "formOption:"+option.getId();
            Boolean flag3 = redisObjectComponent.del(key3);
            log.info("清除选项缓存，delete key={} from redis result={}", key3, flag3);
        }
        int maxOrder = surveyQuestionMapper.getMaxOrderByFormId(surveyQuestion.getFormId());
        int result = surveyQuestionMapper.deleteByPrimaryKey(param.getQuestionId());
        int result2 = surveyOptionMapper.deleteByQuestionId(param.getQuestionId());
        if(surveyQuestion.getQuestionOrder().intValue()<maxOrder){
            surveyQuestion.setUpdateTime(new Date(System.currentTimeMillis()));
            int result3 = surveyQuestionMapper.batchUpdateQuestionOrder(surveyQuestion);
            return result3;
        }
        return result+result2;
    }


    public int deleteOption(Option param){
        SurveyOption surveyOption = surveyOptionMapper.selectByPrimaryKey(param.getOptionId());
        if(surveyOption==null){
            return 0;
        }
        SurveyQuestion surveyQuestion = surveyQuestionMapper.selectByPrimaryKey(surveyOption.getQuestionId());
        if(surveyQuestion==null){
            return 0;
        }

        //清除formResult的缓存：redis中formResult:formId缓存
        String key = "formResult:"+surveyQuestion.getFormId();
        Boolean flag = redisObjectComponent.del(key);
        log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);

        //清除formQuestion的缓存：redis中formQuestion:questionId缓存
        String key2 = "formQuestion:"+surveyQuestion.getId();
        Boolean flag2 = redisObjectComponent.del(key2);
        log.info("清除题目缓存，delete key={} from redis result={}", key2, flag2);

        //清除formOption的缓存：redis中formOption:optionId缓存
        String key3 = "formOption:"+surveyOption.getId();
        Boolean flag3 = redisObjectComponent.del(key3);
        log.info("清除选项缓存，delete key={} from redis result={}", key3, flag3);

        Integer maxOrder = surveyOptionMapper.getMaxOrderByQuestionId(surveyOption.getQuestionId());
        if(maxOrder==null){
            maxOrder=0;
        }


        int result = surveyOptionMapper.deleteByPrimaryKey(param.getOptionId());
        if(surveyOption.getOptionOrder().intValue()<maxOrder) {
            surveyOption.setUpdateTime(new Date(System.currentTimeMillis()));
            int result2 = surveyOptionMapper.batchUpdateOptionOrder(surveyOption);
            return result2;
        }
        return result;
    }

    /**
     * 创建题目的单个选项
     * @param param
     * @return
     */
    public Result createOption(Option param){
        Integer questionId = param.getQuestionId();
        SurveyQuestion surveyQuestion = surveyQuestionMapper.selectByPrimaryKey(questionId);

        SurveyOption option = new SurveyOption();
        option.setFormId(surveyQuestion.getFormId());
        option.setQuestionId(param.getQuestionId());
        option.setOptionTitle(param.getLabel());
        option.setOptionOrder(param.getValue());
        option.setOptionIcon(param.getImageUrl());

        if(param.getExplain()!=null){
            option.setOptionDescription(param.getExplain().getLabel());
            option.setIsDisplayOptionDescription(param.getExplain().getValue()?1:0);
            option.setOptionDetail(param.getExplain().getDetail());
            option.setEnableExLink(param.getExplain().getExLink()?1:0);
            option.setExLinkUrl(param.getExplain().getLinkUrl());
        }

        Date currentTime = new Date(System.currentTimeMillis());
        option.setUpdateTime(currentTime);
        option.setCreateTime(currentTime);

        if(option.getOptionDetail()==null){
            option.setOptionDetail("");
        }
        int result = surveyOptionMapper.insertSelective(option);
        if(result>0){
            //清除formResult的缓存：redis中formResult:formId缓存
            String key = "formResult:"+surveyQuestion.getFormId();
            Boolean flag = redisObjectComponent.del(key);
            log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);
            return Result.success(option);
        }else{
            return Result.error("保存题目的选项失败", "保存题目的选项失败");
        }
    }


    /**
     *
     * @param param
     * @return
     */
    public Result updateOption(Option param){
        SurveyOption option = new SurveyOption();
        option.setId(param.getOptionId());
        option.setOptionTitle(param.getLabel());
        //option.setOptionOrder(param.getValue());
        option.setOptionIcon(param.getImageUrl());

        if(param.getExplain()!=null) {
            option.setOptionDescription(param.getExplain().getLabel());
            option.setIsDisplayOptionDescription(param.getExplain().getValue() ? 1 : 0);
            option.setOptionDetail(param.getExplain().getDetail());
            option.setEnableExLink(param.getExplain().getExLink() ? 1 : 0);
            option.setExLinkUrl(param.getExplain().getLinkUrl());
        }

        Date currentTime = new Date(System.currentTimeMillis());
        option.setUpdateTime(currentTime);

        int result = surveyOptionMapper.updateByPrimaryKeySelective(option);
        if(result>0){
            //清除formResult的缓存：redis中formResult:formId缓存
            SurveyOption dbOption = surveyOptionMapper.selectByPrimaryKey(option.getId());
            String key = "formResult:"+dbOption.getFormId();
            Boolean flag = redisObjectComponent.del(key);
            log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);

            //清除formOption的缓存：redis中formOption:optionId缓存
            String key2 = "formOption:"+dbOption.getId();
            Boolean flag2 = redisObjectComponent.del(key2);
            log.info("清除formOption缓存，delete key={} from redis result={}", key2, flag2);

            return Result.success("更新题目的选项成功");
        }else{
            return Result.error("更新题目的选项失败", "更新题目的选项失败");
        }
    }


    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result moveOption(MoveOptionParam param){
        SurveyOption surveyOption = null;
        if(param.getOptionId()==null){//该Option还没有创建，先创建该Option
            return Result.error("该选项还没有创建，不能移动", "该选项还没有创建，不能移动");
        }else{
            surveyOption = surveyOptionMapper.selectByPrimaryKey(param.getOptionId());
            if(surveyOption==null){
                log.info("没有这个题目选项，optionId={}", param.getOptionId());
                return Result.error("没有这个题目选项，optionId="+param.getOptionId(), "没有这个题目选项，optionId="+param.getOptionId());
            }
        }
        int toOrder = param.getToOrder();
        int fromOrder = surveyOption.getOptionOrder();
        if(fromOrder==toOrder){
            log.info("源目标与移动目标相同，无需移动");
            return Result.error("源目标与移动目标相同，无需移动", "源目标与移动目标相同，无需移动");
        }
        //为避免unique限制，将optionOrder暂时设置为0
        surveyOption.setOptionOrder(0);
        int result = surveyOptionMapper.updateOptionOrderByPrimaryKey(surveyOption);

        if(result>0) {
            //清除formResult的缓存：redis中formResult:formId缓存
            String key = "formResult:"+surveyOption.getFormId();
            Boolean flag = redisObjectComponent.del(key);
            log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);

            //清除formOption的缓存：redis中formOption:optionId缓存
            String key2 = "formOption:"+surveyOption.getId();
            Boolean flag2 = redisObjectComponent.del(key2);
            log.info("清除formOption缓存，delete key={} from redis result={}", key2, flag2);

            int count = 0;
            param.setFromOrder(fromOrder);
            param.setQuestionId(surveyOption.getQuestionId());
            if (fromOrder < toOrder) {//向后移动
                count = surveyOptionMapper.updateOrderForBack(param);
                log.info("id={}， fromOrder={}， toOrder={}向后移动结果={}", param.getOptionId(), fromOrder, toOrder, count);
            }else{//向前移动
                count = surveyOptionMapper.updateOrderForFront(param);
                log.info("id={}， fromOrder={}， toOrder={}向前移动结果={}", param.getOptionId(), fromOrder, toOrder, count);
            }
            if(count>0){
                //设置选项的顺序为应该的值toOrder
                surveyOption.setOptionOrder(toOrder);
                surveyOption.setUpdateTime(new Date(System.currentTimeMillis()));
                result = surveyOptionMapper.updateOptionOrderByPrimaryKey(surveyOption);
                log.info("更新题目选项optionId={}的optionOrder={}的结果={}", surveyOption.getId(), toOrder, result);
                if(result>0) {
                    return Result.success(surveyOption);
                }
            }
        }
        return Result.error("移动题目选项失败", "移动题目选项失败");
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result moveQuestion(MoveQuestionParam param){
        SurveyQuestion surveyQuestion = null;
        if(param.getQuestionId()==null){//该Question还没有创建，先创建该Question
            surveyQuestion = new SurveyQuestion();
            surveyQuestion.setFormId(param.getFormId());
            //将该surveyOption的optionOrder设置为最大order+1
            int maxOrder = surveyQuestionMapper.getMaxOrderByFormId(param.getFormId());
            surveyQuestion.setQuestionOrder(maxOrder+1);
            surveyQuestion.setQuestionTitle("");
            Date currentTime = new Date(System.currentTimeMillis());
            surveyQuestion.setCreateTime(currentTime);
            surveyQuestion.setUpdateTime(currentTime);
            int result = surveyQuestionMapper.insertSelective(surveyQuestion);
            if(result>0){
                param.setQuestionId(surveyQuestion.getId());
            }
        }
        int toOrder = param.getToOrder();
        surveyQuestion = surveyQuestionMapper.selectByPrimaryKey(param.getQuestionId());
        if(surveyQuestion==null){
            log.info("没有这个题目，questionId={}", param.getQuestionId());
            return Result.error("没有这个题目，questionId="+param.getQuestionId(), "没有这个题目，questionId="+param.getQuestionId());
        }
        int fromOrder = surveyQuestion.getQuestionOrder();
        if(fromOrder==toOrder){
            log.info("源目标与移动目标相同，无需移动");
            return Result.error("源目标与移动目标相同，无需移动", "源目标与移动目标相同，无需移动");
        }
        //为避免unique限制，将optionOrder暂时设置为0
        surveyQuestion.setQuestionOrder(0);
        int result = surveyQuestionMapper.updateQuestionOrderByPrimaryKey(surveyQuestion);

        if(result>0) {
            //清除formResult的缓存：redis中formResult:formId缓存
            String key = "formResult:"+surveyQuestion.getFormId();
            Boolean flag = redisObjectComponent.del(key);
            log.info("清除formResult缓存，delete key={} from redis result={}", key, flag);

            //清除formQuestion的缓存：redis中formQuestion:questionId缓存
            String key2 = "formQuestion:"+surveyQuestion.getId();
            Boolean flag2 = redisObjectComponent.del(key2);
            log.info("清除formQuestion缓存，delete key={} from redis result={}", key2, flag2);

            int count = 0;
            param.setFromOrder(fromOrder);
            param.setFormId(surveyQuestion.getFormId());
            if (fromOrder < toOrder) {//向后移动
                count = surveyQuestionMapper.updateOrderForBack(param);
                log.info("id={}， fromOrder={}， toOrder={}向后移动结果={}", param.getQuestionId(), fromOrder, toOrder, count);
            }else{//向前移动
                count = surveyQuestionMapper.updateOrderForFront(param);
                log.info("id={}， fromOrder={}， toOrder={}向前移动结果={}", param.getQuestionId(), fromOrder, toOrder, count);
            }
            if(count>0){
                //设置选项的顺序为应该的值toOrder
                surveyQuestion.setQuestionOrder(toOrder);
                surveyQuestion.setUpdateTime(new Date(System.currentTimeMillis()));
                result = surveyQuestionMapper.updateQuestionOrderByPrimaryKey(surveyQuestion);
                log.info("更新题目选项optionId={}的optionOrder={}的结果={}", surveyQuestion.getId(), toOrder, result);
                if(result>0) {
                    return Result.success(surveyQuestion);
                }
            }
        }
        return Result.error("移动题目失败", "移动题目失败");
    }


    /**
     * 根据题目id获取题目及选项
     * @param questionId
     * @return
     */
    public QuestionAndOptionParam getQuestionAndOption(Integer questionId){
        SurveyQuestion surveyQuestion = surveyQuestionMapper.selectByPrimaryKey(questionId);
        List<SurveyOption> optionList = surveyOptionMapper.selectByQuestionId(questionId);

        QuestionParam questionParam = buildQuestionParam(surveyQuestion);
        OptionParam optionParam = buildOptionParam(optionList);

        QuestionAndOptionParam questionAndOptionParam = new QuestionAndOptionParam();
        questionAndOptionParam.setQuestionParam(questionParam);
        questionAndOptionParam.setOptionParam(optionParam);

        return questionAndOptionParam;
    }

    /**
     * 根据题目对象获取题目及选项
     * @param surveyQuestion
     * @return
     */
    public QuestionAndOptionParam getQuestionAndOption(SurveyQuestion surveyQuestion){
        List<SurveyOption> optionList = surveyOptionMapper.selectByQuestionId(surveyQuestion.getId());

        QuestionParam questionParam = buildQuestionParam(surveyQuestion);
        OptionParam optionParam = buildOptionParam(optionList);

        QuestionAndOptionParam questionAndOptionParam = new QuestionAndOptionParam();
        questionAndOptionParam.setQuestionParam(questionParam);
        questionAndOptionParam.setOptionParam(optionParam);

        return questionAndOptionParam;
    }

    /**
     * 根据formId获取表单所有题目及选项
     * @param formId
     * @return
     */
    public FormParam getAllQuestionAndOptionByFormId(String formId){
        FormParam formParam = new FormParam();
        SurveyForm surveyForm = surveyFormMapper.getSurveyFormByFormId(formId);

        SurveyFormParam surveyFormParam = new SurveyFormParam();
        BeanUtil.copyProperties(surveyForm, surveyFormParam);
        formParam.setSurveyFormParam(surveyFormParam);

        List<SurveyQuestion> surveyQuestions = surveyQuestionMapper.selectByFormId(formId);
        List<QuestionAndOptionParam> questions = new ArrayList<QuestionAndOptionParam>();
        for(SurveyQuestion question:surveyQuestions){
            QuestionAndOptionParam questionAndOptionParam = getQuestionAndOption(question);
            questions.add(questionAndOptionParam);
        }
        formParam.setQuestions(questions);
        return formParam;
    }

    /**
     *
     * @param formId
     * @return
     */
    public Result restoreForm(String formId){
        SurveyForm surveyForm = this.getFormByFormId(formId);
        if(surveyForm==null){
            return Result.error("没有这个表单", "没有这个表单");
        }
        if(surveyForm.getIsDelete().intValue()!=1){//不是删除状态
            return Result.error("表单不是删除状态，不能恢复", "表单不是删除状态，不能恢复");
        }
        surveyForm.setIsDelete(0);
        surveyForm.setUpdateTime(new Date(System.currentTimeMillis()));
        int result = surveyFormMapper.updateIsDeleteByFormId(surveyForm);
        if(result>0){
            return Result.success("从回收站恢复表单成功");
        }else{
            return Result.error("从回收站恢复表单失败", "从回收站恢复表单失败");
        }
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result deleteFormFromRecycle(String formId, Users user){
        SurveyForm surveyForm = getFormByFormId(formId);
        if(surveyForm==null){
            return Result.error("没有这个表单", "没有这个表单");
        }
        if(surveyForm.getIsDelete()!=1){
            return Result.error("表单不在回收站中，不能永久删除", "表单不在回收站中，不能永久删除");
        }
        //物理删除该表单下的选项
        int deleteOptionResult = surveyOptionMapper.deleteByFormId(formId);
        //物理删除该表单下的题目
        int deleteQuestionResult = surveyQuestionMapper.deleteByFormId(formId);
        //物理删除表单配置
        int deleteFormConfigResult = surveyFormConfigMapper.deleteByFormId(formId);
        //物理删除表单
        int deleteFormResult = surveyFormMapper.deleteByFormId(formId);
        if(deleteFormResult>0){
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(formId);
            operationLog.setDataType(1);
            operationLog.setUserId(user.getUserid());
            operationLog.setActionType(5);
            operationLog.setActionName("从回收站永久删除表单");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);

            return Result.success("从回收站永久删除表单成功");
        }else{
            return Result.error("从回收站永久删除表单失败", "从回收站永久删除表单失败");
        }
    }

    public Result clearFormInRecycle(Users user){
        //查询回收站中所有表单
        List<SurveyForm> surveyFormList = surveyFormMapper.listFormByIsDelete(1);
        for(SurveyForm surveyForm:surveyFormList){
            this.deleteFormFromRecycle(surveyForm.getFormId(), user);
        }
        return Result.success("清空表单回收站成功");
    }

    @Override
    public Result loadSurveyFormData(FrontSurveyParam param, HttpServletRequest request) {
        // 请求源referer判定
        String referer = request.getHeader("referer");
        log.info("当前请求的referer={}",referer);
        if (("prod").equals(activeProfile)){
            if (!referer.contains("form.caigou2003.com") && !referer.contains("mform.caigou2003.com")){
                log.error("当前请求的referer不符合规则，不进行请求处理");
                return Result.success(ResponseEnum.SUCCESS);
            }
        }
        // 如果请求参数不符合加密规则，则不进行处理
        String str = param.getUserId()+param.getDeviceId()+param.getSource()+param.getPlatform()+param.getTimestamp()+param.getRequestIp();// 将所有辨识用户的参数拼接在一起
        String encode1 = Md5Util.MD5_32bit(str, "UTF-8");// 将拼装之后的字符串进行MD5加密
        String encode = Md5Util.MD5_32bit(encode1+"caigou2003.com","UTF-8");
        if (!param.getSign().equals(encode)) {
            log.error("加密参数验证异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 参数异常判定(时间戳字段，如果超出当前时间5S则认定的是异常请求)
        long nowTime = System.currentTimeMillis()/1000;
        log.info("当前系统时间 time={}",nowTime);
        if (param.getTimestamp() > (nowTime+3) || param.getTimestamp() < (nowTime-2)){
            log.error("请求时间戳字段异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 获取表单主表数据
        SurveyForm form = (SurveyForm) redisObjectComponent.get("form:"+param.getFormId());
        if (null == form){
            log.info("缓存中获取不到form数据，进行mysql获取");
            form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
            if (null != form){
                log.info("进行form主表缓存存储");
                redisObjectComponent.set("form:"+param.getFormId(), form);
            }
        }
        if (null == form) {
            log.info("获取的form数据不存在");
            return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 数据不存在或未发布则不能访问
        }
        if (form.getIsEnable() == 0) {
            log.info("获取的form数据未发布");
            return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
        }
        // 获取表单关联目录的状态
        if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
            log.info("接口中未传递catalogId参数，获取当前表单是否关联了目录");
            param.setCatalogId(redisComponent.get("formCatalog:"+param.getFormId()));
            if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
                log.info("缓存中未获取到catalogId参数，从数据库获取");
                param.setCatalogId(surveyCatalogMapper.loadCatalogIdByForm(param.getFormId()));
                if (null != param.getCatalogId() && !("").equals(param.getCatalogId())){
                    log.info("进行表单目录关联关系的缓存存储");
                    redisComponent.set("formCatalog:"+param.getFormId(),param.getCatalogId());
                }
            }
        }
        // 获取目录配置表数据
        SurveyCatalogConfig config = (SurveyCatalogConfig) redisObjectComponent.get("catalogConfig:"+param.getCatalogId());
        if (null == config){// 当数据库获取数据不为空的时候进行缓存
            config = surveyCatalogMapper.loadSurveyCatalogConfig(param.getCatalogId());
            if (null != config){
                log.info("进行目录配置的缓存存储");
                redisObjectComponent.set("catalogConfig:"+param.getCatalogId(),config);
            }
        }
        // 获取表单配置表数据
        SurveyFormConfig formConfig = (SurveyFormConfig) redisObjectComponent.get("formConfig:"+param.getFormId());
        if (null == formConfig){
            formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            if (null != formConfig){// 当数据库获取数据不为空的时候进行缓存
                log.info("进行表单配置的缓存存储");
                redisObjectComponent.set("formConfig:"+param.getFormId(),formConfig);
            }
        }
        // 封装返回数据
        SurveyFormData form1 = (SurveyFormData) redisObjectComponent.get("formResult:"+param.getFormId());
        if (null == form1){
            form1 = surveyFormMapper.loadSurveyFormData(param.getFormId());
            // 获取表单的二维码列表
            List<SurveyQRListData> qrList = sharePlatformMapper.loadSurveyQRListData(param.getFormId());
            form1.setQrList(qrList);
            // TODO: 2021/6/21 0021 获取表单的广告列表
            // 获取表单的题目列表
            List<SurveyFormQuestionListData> questionList = surveyQuestionMapper.loadSurveyFormQuestionListData(param.getFormId());
            form1.setList(questionList);
            form1.getList().forEach(question -> {
                // 获取题目选项列表
                List<SurveyFormOptionListData> optionList = surveyOptionMapper.loadSurveyFormOptionListData(param.getFormId(),question.getQuestionId());
                question.setList(optionList);
            });
            redisObjectComponent.set("formResult:"+param.getFormId(),form1);
        }
        // 封装头部返回数据
        SurveyFormData surveyFormData = new SurveyFormData();
        surveyFormData.setFormTitle(form1.getFormTitle());
        surveyFormData.setIsDisplayDescription(form1.getIsDisplayDescription());
        surveyFormData.setDescriptionType(form1.getDescriptionType());
        surveyFormData.setFormDescription(form1.getFormDescription());
        surveyFormData.setIsDisplayBanner(form1.getIsDisplayBanner());
        surveyFormData.setFormBanner(form1.getFormBanner());
        surveyFormData.setQrList(form1.getQrList());
        surveyFormData.setBannerList(form1.getBannerList());
        // 获取权限属性
        int permission;
        boolean permissionResult = false;
        if (null != param.getUserId() && !("").equals(param.getUserId())){
            permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getUserId());
        }
        if (!permissionResult){
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){
                permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getDeviceId());
            }
            if (permissionResult){
                log.info("可以根据deviceId字段获取到权限值");
                permission = 1;
            } else {
                log.info("两个参数都获取不到缓存值，进行mysql数据读取");
                permission = surveyPermissionService.loadSurveyPermission(null == param.getCatalogId() ? "" : param.getCatalogId(),param.getFormId(),param.getUserId(),param.getDeviceId());
                if (permission == 1){
                    log.info("从缓存中获取到了权限，进行权限数据的缓存存储");
                    if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
                    if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
                }
            }
        } else {
            log.info("可以根据userId字段获取到权限值");
            permission = 1;
        }
        // 进行配置数据的判定
        if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
            if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
            log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
            if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                surveyFormData.setStartTime(formConfig.getStartTime());
                surveyFormData.setEndTime(formConfig.getEndTime());
                if (result == 2) {
                    log.error("当前表单目录设置开始时间未到");
                    return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                }
                if (result == 3) {
                    log.error("当前表单目录设置结束时间已到");
                    return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                }
            }
            if (formConfig.getVerifyType() == 0){// 开启登录验证
                if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                    log.error("当前表单目录设置登录验证未通过");
                    return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                }
            }
            if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                if (permission == 0) {
                    log.error("当前表单目录设置邀请码验证未通过");
                    return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                }
            }
        } else {
            if (config.getConfigType() == 1){// 目录设置为按表单需求设置，使用表单配置属性
                if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                log.info("目录设置为按表单需求设置，使用表单配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(formConfig.getStartTime());
                    surveyFormData.setEndTime(formConfig.getEndTime());
                    int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                    }
                }
                if (formConfig.getVerifyType() == 0){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                    log.error("当前表单表单设置邀请码验证未通过");
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            } else {// 目录设置为所有表单使用此设置，使用目录配置属性
                log.info("目录设置为所有表单使用此设置，使用目录配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                // 按照目录页设置判定
                if (config.getTimeStatus() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(config.getStartTime());
                    surveyFormData.setEndTime(config.getEndTime());
                    int result = DateUtil.confineToDate(config.getStartTime(),config.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),config.getStartTimeErr(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),config.getEndTimeErr(),surveyFormData);
                    }
                }
                if (config.getAuthType() == 1){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (config.getAuthCodeStatus() == 1){// 开启邀请码验证
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            }
        }
        if (permission == 1) {// 用户拥有对应权限
            // 提交次数验证
            int userCount = surveySubmitMapper.loadUserAnswerCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户已回答次数
            int todayCount = surveySubmitMapper.loadUserTodayCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户今日回答次数
            if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
                log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
                switch (formConfig.getFillRestriction()){
                    case 1:// 每人填写一次（一共）
                        if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR,surveyFormData);
                        break;
                    case 2:// 每人每天填写两次
                        if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                        break;
                    case 3:// 每人每天填写三次
                        if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                        break;
                }
            } else {
                if (config.getConfigType() == 1){
                    if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                    log.info("目录设置为，按表单需求设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (formConfig.getFillRestriction()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR,surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                    }
                } else {
                    log.info("目录设置为，所有目录内表单使用此设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (config.getFillType()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR,surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                    }
                }
            }
            // 处理返回的数据
            form1.getList().forEach(question -> question.getList().forEach(answer -> {
                // 获取选项数据
                SurveyFormOptionListData optionListData = (SurveyFormOptionListData) redisObjectComponent.get("formOption:"+answer.getOptionId());
                if (null == optionListData){
                    optionListData = surveyOptionMapper.loadSurveyFormOptionListDataById(answer.getOptionId());
                }
                // 获取选项提交次数
                if (null == redisComponent.hget("formOptionSubmitCount", answer.getOptionId().toString())){// 没有当前选项提交次数的缓存
                    answer.setSubmitCount(optionListData.getSubmitCount()+optionListData.getChangeCount());
                    redisComponent.hset("formOptionSubmitCount", answer.getOptionId().toString(), String.valueOf(optionListData.getSubmitCount()+optionListData.getChangeCount()));
                } else {
                    int submitCount = Integer.parseInt(redisComponent.hget("formOptionSubmitCount", answer.getOptionId().toString()).toString());
                    log.info("缓存中获取的选项提交次数为submitCount={}",submitCount);
                    answer.setSubmitCount(submitCount);
                }
            }));
        } else {
            if (null == param.getUserId() || null == param.getDeviceId()){
                return Result.success(ResponseEnum.SUCCESS);
            }
            // 登录验证、邀请码验证、时间段验证都通过之后，进行权限数据保存
            SurveyPermission surveyPermission = new SurveyPermission();
            surveyPermission.setCatalogId(null == param.getCatalogId() ? "" : param.getCatalogId());
            surveyPermission.setFormId(param.getFormId());
            surveyPermission.setUserId(param.getUserId());
            surveyPermission.setDeviceId(param.getDeviceId());
            int result = surveyPermissionService.saveSurveyPermission(surveyPermission);
            log.info("权限验证通过，保存用户权限数据 result={}", result);
            if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
        }
        // 处理返回数据
        form1.getList().forEach(question -> question.getList().forEach(answer -> {
            // 获取选项数据
            SurveyFormOptionListData optionListData = (SurveyFormOptionListData) redisObjectComponent.get("formOption:"+answer.getOptionId());
            if (null == optionListData){
                optionListData = surveyOptionMapper.loadSurveyFormOptionListDataById(answer.getOptionId());
            }
            // 获取选项提交次数
            if (null == redisComponent.hget("formOptionSubmitCount", answer.getOptionId().toString())){// 没有当前选项提交次数的缓存
                answer.setSubmitCount(optionListData.getSubmitCount()+optionListData.getChangeCount());
                redisComponent.hset("formOptionSubmitCount", answer.getOptionId().toString(), String.valueOf(optionListData.getSubmitCount()+optionListData.getChangeCount()));
            } else {
                int submitCount = Integer.parseInt(redisComponent.hget("formOptionSubmitCount", answer.getOptionId().toString()).toString());
                log.info("缓存中获取的选项提交次数为submitCount={}",submitCount);
                answer.setSubmitCount(submitCount);
            }
        }));
        // 确定详情页获取完成--增加该表单的访问次数
        SurveyFormStatistics formStatistics = new SurveyFormStatistics();
        formStatistics.setFormId(param.getFormId());
        switch (param.getSource()){
            case 1:
                formStatistics.setPcCheckCount(1);
                break;
            case 2:
                formStatistics.setAppCheckCount(1);
                break;
            case 3:
                formStatistics.setYktCheckCount(1);
                break;
            case 4:
                formStatistics.setYzbCheckCount(1);
                break;
            case 5:
                formStatistics.setWxCheckCount(1);
                break;
        }
        rabbitProducer.sendFormSaveStatisticsMessage(formStatistics);
        return Result.success(form1);
    }

    @Override
    public Result loadSurveyFormOptionData(FrontSurveyParam param, HttpServletRequest request) {
        // 请求源referer判定
        String referer = request.getHeader("referer");
        log.info("当前请求的referer={}",referer);
        if (("prod").equals(activeProfile)){
            if (!referer.contains("form.caigou2003.com") && !referer.contains("mform.caigou2003.com")){
                log.error("当前请求的referer不符合规则，不进行请求处理");
                return Result.success(ResponseEnum.SUCCESS);
            }
        }
        // 如果请求参数不符合加密规则，则不进行处理
        String str = param.getUserId()+param.getDeviceId()+param.getSource()+param.getPlatform()+param.getTimestamp()+param.getRequestIp();// 将所有辨识用户的参数拼接在一起
        String encode1 = Md5Util.MD5_32bit(str, "UTF-8");// 将拼装之后的字符串进行MD5加密
        String encode = Md5Util.MD5_32bit(encode1+"caigou2003.com","UTF-8");
        if (!param.getSign().equals(encode)) {
            log.error("加密参数验证异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 参数异常判定(时间戳字段，如果超出当前时间5S则认定的是异常请求)
        long nowTime = System.currentTimeMillis()/1000;
        log.info("当前系统时间 time={}",nowTime);
        if (param.getTimestamp() > (nowTime+3) || param.getTimestamp() < (nowTime-2)){
            log.error("请求时间戳字段异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 获取表单主表数据
        SurveyForm form = (SurveyForm) redisObjectComponent.get("form:"+param.getFormId());
        if (null == form){
            log.info("缓存中获取不到form数据，进行mysql获取");
            form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
            if (null != form){
                log.info("进行form主表缓存存储");
                redisObjectComponent.set("form:"+param.getFormId(), form);
            }
        }
        if (null == form) {
            log.info("获取的form数据不存在");
            return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 数据不存在或未发布则不能访问
        }
        if (form.getIsEnable() == 0) {
            log.info("获取的form数据未发布");
            return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
        }
        // 获取表单关联目录的状态
        if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
            log.info("接口中未传递catalogId参数，获取当前表单是否关联了目录");
            param.setCatalogId(redisComponent.get("formCatalog:"+param.getFormId()));
            if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
                log.info("缓存中未获取到catalogId参数，从数据库获取");
                param.setCatalogId(surveyCatalogMapper.loadCatalogIdByForm(param.getFormId()));
                if (null != param.getCatalogId() && !("").equals(param.getCatalogId())){
                    log.info("进行表单目录关联关系的缓存存储");
                    redisComponent.set("formCatalog:"+param.getFormId(),param.getCatalogId());
                }
            }
        }
        // 获取目录配置表数据
        SurveyCatalogConfig config = (SurveyCatalogConfig) redisObjectComponent.get("catalogConfig:"+param.getCatalogId());
        if (null == config){// 当数据库获取数据不为空的时候进行缓存
            config = surveyCatalogMapper.loadSurveyCatalogConfig(param.getCatalogId());
            if (null != config){
                log.info("进行目录配置的缓存存储");
                redisObjectComponent.set("catalogConfig:"+param.getCatalogId(),config);
            }
        }
        // 获取表单配置表数据
        SurveyFormConfig formConfig = (SurveyFormConfig) redisObjectComponent.get("formConfig:"+param.getFormId());
        if (null == formConfig){
            formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            if (null != formConfig){// 当数据库获取数据不为空的时候进行缓存
                log.info("进行表单配置的缓存存储");
                redisObjectComponent.set("formConfig:"+param.getFormId(),formConfig);
            }
        }
        // 封装返回数据
        SurveyFormData form1 = (SurveyFormData) redisObjectComponent.get("formResult:"+param.getFormId());
        if (null == form1){
            form1 = surveyFormMapper.loadSurveyFormData(param.getFormId());
            // 获取表单的二维码列表
            List<SurveyQRListData> qrList = sharePlatformMapper.loadSurveyQRListData(param.getFormId());
            form1.setQrList(qrList);
            // TODO: 2021/6/21 0021 获取表单的广告列表
            // 获取表单的题目列表
            List<SurveyFormQuestionListData> questionList = surveyQuestionMapper.loadSurveyFormQuestionListData(param.getFormId());
            form1.setList(questionList);
            form1.getList().forEach(question -> {
                // 获取题目选项列表
                List<SurveyFormOptionListData> optionList = surveyOptionMapper.loadSurveyFormOptionListData(param.getFormId(),question.getQuestionId());
                question.setList(optionList);
            });
            redisObjectComponent.set("formResult:"+param.getFormId(),form1);
        }
        // 封装头部返回数据
        SurveyFormData surveyFormData = new SurveyFormData();
        surveyFormData.setFormTitle(form1.getFormTitle());
        surveyFormData.setIsDisplayDescription(form1.getIsDisplayDescription());
        surveyFormData.setDescriptionType(form1.getDescriptionType());
        surveyFormData.setFormDescription(form1.getFormDescription());
        surveyFormData.setIsDisplayBanner(form1.getIsDisplayBanner());
        surveyFormData.setFormBanner(form1.getFormBanner());
        surveyFormData.setQrList(form1.getQrList());
        surveyFormData.setBannerList(form1.getBannerList());
        // 获取权限属性
        int permission;
        boolean permissionResult = false;
        if (null != param.getUserId() && !("").equals(param.getUserId())){
            permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getUserId());
        }
        if (!permissionResult){
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){
                permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getDeviceId());
            }
            if (permissionResult){
                log.info("可以根据deviceId字段获取到权限值");
                permission = 1;
            } else {
                log.info("两个参数都获取不到缓存值，进行mysql数据读取");
                permission = surveyPermissionService.loadSurveyPermission(null == param.getCatalogId() ? "" : param.getCatalogId(),param.getFormId(),param.getUserId(),param.getDeviceId());
                if (permission == 1){
                    log.info("从缓存中获取到了权限，进行权限数据的缓存存储");
                    if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
                    if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
                }
            }
        } else {
            log.info("可以根据userId字段获取到权限值");
            permission = 1;
        }
        // 进行配置数据的判定
        if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
            if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
            log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
            if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                surveyFormData.setStartTime(formConfig.getStartTime());
                surveyFormData.setEndTime(formConfig.getEndTime());
                if (result == 2) {
                    log.error("当前表单目录设置开始时间未到");
                    return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                }
                if (result == 3) {
                    log.error("当前表单目录设置结束时间已到");
                    return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                }
            }
            if (formConfig.getVerifyType() == 0){// 开启登录验证
                if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                    log.error("当前表单目录设置登录验证未通过");
                    return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                }
            }
            if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                if (permission == 0) {
                    log.error("当前表单目录设置邀请码验证未通过");
                    return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                }
            }
        } else {
            if (config.getConfigType() == 1){// 目录设置为按表单需求设置，使用表单配置属性
                if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                log.info("目录设置为按表单需求设置，使用表单配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(formConfig.getStartTime());
                    surveyFormData.setEndTime(formConfig.getEndTime());
                    int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                    }
                }
                if (formConfig.getVerifyType() == 0){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                    log.error("当前表单表单设置邀请码验证未通过");
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            } else {// 目录设置为所有表单使用此设置，使用目录配置属性
                log.info("目录设置为所有表单使用此设置，使用目录配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                // 按照目录页设置判定
                if (config.getTimeStatus() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(config.getStartTime());
                    surveyFormData.setEndTime(config.getEndTime());
                    int result = DateUtil.confineToDate(config.getStartTime(),config.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),config.getStartTimeErr(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),config.getEndTimeErr(),surveyFormData);
                    }
                }
                if (config.getAuthType() == 1){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (config.getAuthCodeStatus() == 1){// 开启邀请码验证
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            }
        }
        // 提交次数判定
        if (permission == 1) {// 用户拥有对应权限
            // 提交次数验证
            int userCount = surveySubmitMapper.loadUserAnswerCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户已回答次数
            int todayCount = surveySubmitMapper.loadUserTodayCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户今日回答次数
            if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
                log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
                switch (formConfig.getFillRestriction()){
                    case 1:// 每人填写一次（一共）
                        if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR, surveyFormData);
                        break;
                    case 2:// 每人每天填写两次
                        if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                        break;
                    case 3:// 每人每天填写三次
                        if (todayCount >= 3) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                        break;
                }
            } else {
                if (config.getConfigType() == 1){
                    if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                    log.info("目录设置为，所有目录内表单使用此设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (formConfig.getFillRestriction()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR, surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount >= 3) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                    }
                } else {
                    log.info("目录设置为，按表单需求设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (config.getFillType()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR, surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount >= 3) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR, surveyFormData);
                            break;
                    }
                }
            }
        } else {
            if (null == param.getUserId() || null == param.getDeviceId()){
                return Result.success(ResponseEnum.SUCCESS);
            }
            // 登录验证、邀请码验证、时间段验证都通过之后，进行权限数据保存
            SurveyPermission surveyPermission = new SurveyPermission();
            surveyPermission.setCatalogId(null == param.getCatalogId() ? "" : param.getCatalogId());
            surveyPermission.setFormId(param.getFormId());
            surveyPermission.setUserId(param.getUserId());
            surveyPermission.setDeviceId(param.getDeviceId());
            int result = surveyPermissionService.saveSurveyPermission(surveyPermission);
            log.info("权限验证通过，保存用户权限数据 result={}", result);
            if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
        }
        // 获取选项数据
        SurveyFormOptionListData optionListData = (SurveyFormOptionListData) redisObjectComponent.get("formOption:"+param.getOptionId());
        if (null == optionListData){
            optionListData = surveyOptionMapper.loadSurveyFormOptionListDataById(param.getOptionId());
        }
        // 获取选项提交次数
        if (null == redisComponent.hget("formOptionSubmitCount", param.getOptionId().toString())){// 没有当前选项提交次数的缓存
            optionListData.setSubmitCount(optionListData.getSubmitCount()+optionListData.getChangeCount());
            redisComponent.hset("formOptionSubmitCount", param.getOptionId().toString(), String.valueOf(optionListData.getSubmitCount()+optionListData.getChangeCount()));
        } else {
            int submitCount = Integer.parseInt(redisComponent.hget("formOptionSubmitCount", param.getOptionId().toString()).toString());
            log.info("缓存中获取的选项提交次数为submitCount={}",submitCount);
            optionListData.setSubmitCount(submitCount);
        }
        surveyFormData.setOptionListData(optionListData);
        return Result.success(surveyFormData);// 如果有权限数据，则直接返回有权限
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result submitFormAnswer(FrontSurveyParam param, HttpServletRequest request) {
        // 请求源referer判定
        String referer = request.getHeader("referer");
        log.info("当前请求的referer={}",referer);
        if (("prod").equals(activeProfile)){
            if (!referer.contains("form.caigou2003.com") && !referer.contains("mform.caigou2003.com")){
                log.error("当前请求的referer不符合规则，不进行请求处理");
                return Result.success(ResponseEnum.SUCCESS);
            }
        }
        // 如果请求参数不符合加密规则，则不进行处理
        String str = param.getUserId()+param.getDeviceId()+param.getSource()+param.getPlatform()+param.getTimestamp()+param.getRequestIp();// 将所有辨识用户的参数拼接在一起
        String encode1 = Md5Util.MD5_32bit(str, "UTF-8");// 将拼装之后的字符串进行MD5加密
        String encode = Md5Util.MD5_32bit(encode1+"caigou2003.com","UTF-8");
        if (!param.getSign().equals(encode)) {
            log.error("加密参数验证异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 参数异常判定(时间戳字段，如果超出当前时间5S则认定的是异常请求)
        long nowTime = System.currentTimeMillis()/1000;
        log.info("当前系统时间 time={}",nowTime);
        if (param.getTimestamp() > (nowTime+3) || param.getTimestamp() < (nowTime-2)){
            log.error("请求时间戳字段异常");
            return Result.success(ResponseEnum.SUCCESS);
        }
        // 获取表单主表数据
        SurveyForm form = (SurveyForm) redisObjectComponent.get("form:"+param.getFormId());
        if (null == form){
            log.info("缓存中获取不到form数据，进行mysql获取");
            form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
            if (null != form){
                log.info("进行form主表缓存存储");
                redisObjectComponent.set("form:"+param.getFormId(), form);
            }
        }
        if (null == form) {
            log.info("获取的form数据不存在");
            return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 数据不存在或未发布则不能访问
        }
        if (form.getIsEnable() == 0) {
            log.info("获取的form数据未发布");
            return Result.error(ResponseEnum.FRONT_CATALOG_STATUS_ERROR);
        }
        // 获取表单关联目录的状态
        if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
            log.info("接口中未传递catalogId参数，获取当前表单是否关联了目录");
            param.setCatalogId(redisComponent.get("formCatalog:"+param.getFormId()));
            if (null == param.getCatalogId() || ("").equals(param.getCatalogId())){
                log.info("缓存中未获取到catalogId参数，从数据库获取");
                param.setCatalogId(surveyCatalogMapper.loadCatalogIdByForm(param.getFormId()));
                if (null != param.getCatalogId() && !("").equals(param.getCatalogId())){
                    log.info("进行表单目录关联关系的缓存存储");
                    redisComponent.set("formCatalog:"+param.getFormId(),param.getCatalogId());
                }
            }
        }
        // 获取目录配置表数据
        SurveyCatalogConfig config = (SurveyCatalogConfig) redisObjectComponent.get("catalogConfig:"+param.getCatalogId());
        if (null == config){// 当数据库获取数据不为空的时候进行缓存
            config = surveyCatalogMapper.loadSurveyCatalogConfig(param.getCatalogId());
            if (null != config){
                log.info("进行目录配置的缓存存储");
                redisObjectComponent.set("catalogConfig:"+param.getCatalogId(),config);
            }
        }
        // 获取表单配置表数据
        SurveyFormConfig formConfig = (SurveyFormConfig) redisObjectComponent.get("formConfig:"+param.getFormId());
        if (null == formConfig){
            formConfig = surveyService.getSurveyFormConfigByFormId(param.getFormId());
            if (null != formConfig){// 当数据库获取数据不为空的时候进行缓存
                log.info("进行表单配置的缓存存储");
                redisObjectComponent.set("formConfig:"+param.getFormId(),formConfig);
            }
        }
        // 封装返回数据
        SurveyFormData form1 = (SurveyFormData) redisObjectComponent.get("formResult:"+param.getFormId());
        if (null == form1){
            form1 = surveyFormMapper.loadSurveyFormData(param.getFormId());
            // 获取表单的二维码列表
            List<SurveyQRListData> qrList = sharePlatformMapper.loadSurveyQRListData(param.getFormId());
            form1.setQrList(qrList);
            // TODO: 2021/6/21 0021 获取表单的广告列表
            // 获取表单的题目列表
            List<SurveyFormQuestionListData> questionList = surveyQuestionMapper.loadSurveyFormQuestionListData(param.getFormId());
            form1.setList(questionList);
            form1.getList().forEach(question -> {
                // 获取题目选项列表
                List<SurveyFormOptionListData> optionList = surveyOptionMapper.loadSurveyFormOptionListData(param.getFormId(),question.getQuestionId());
                question.setList(optionList);
            });
            redisObjectComponent.set("formResult:"+param.getFormId(),form1);
        }
        // 封装头部返回数据
        SurveyFormData surveyFormData = new SurveyFormData();
        surveyFormData.setFormTitle(form1.getFormTitle());
        surveyFormData.setIsDisplayDescription(form1.getIsDisplayDescription());
        surveyFormData.setDescriptionType(form1.getDescriptionType());
        surveyFormData.setFormDescription(form1.getFormDescription());
        surveyFormData.setIsDisplayBanner(form1.getIsDisplayBanner());
        surveyFormData.setFormBanner(form1.getFormBanner());
        surveyFormData.setQrList(form1.getQrList());
        surveyFormData.setBannerList(form1.getBannerList());
        // 获取权限属性
        int permission;
        boolean permissionResult = false;
        if (null != param.getUserId() && !("").equals(param.getUserId())){
            permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getUserId());
        }
        if (!permissionResult){
            if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){
                permissionResult = redisComponent.sHasKey("formPermission:"+param.getFormId(),param.getDeviceId());
            }
            if (permissionResult){
                log.info("可以根据deviceId字段获取到权限值");
                permission = 1;
            } else {
                log.info("两个参数都获取不到缓存值，进行mysql数据读取");
                permission = surveyPermissionService.loadSurveyPermission(null == param.getCatalogId() ? "" : param.getCatalogId(),param.getFormId(),param.getUserId(),param.getDeviceId());
                if (permission == 1){
                    log.info("从缓存中获取到了权限，进行权限数据的缓存存储");
                    if (null != param.getUserId() && !("").equals(param.getUserId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getUserId()); }
                    if (null != param.getDeviceId() && !("").equals(param.getDeviceId())){ redisComponent.sSet("formPermission:"+param.getFormId(), param.getDeviceId()); }
                }
            }
        } else {
            log.info("可以根据userId字段获取到权限值");
            permission = 1;
        }
        // 进行配置数据的判定
        if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
            if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
            log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
            if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                surveyFormData.setStartTime(formConfig.getStartTime());
                surveyFormData.setEndTime(formConfig.getEndTime());
                if (result == 2) {
                    log.error("当前表单目录设置开始时间未到");
                    return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                }
                if (result == 3) {
                    log.error("当前表单目录设置结束时间已到");
                    return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                }
            }
            if (formConfig.getVerifyType() == 0){// 开启登录验证
                if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                    log.error("当前表单目录设置登录验证未通过");
                    return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                }
            }
            if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                if (permission == 0) {
                    log.error("当前表单目录设置邀请码验证未通过");
                    return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                }
            }
        } else {
            if (config.getConfigType() == 1){// 目录设置为按表单需求设置，使用表单配置属性
                if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                log.info("目录设置为按表单需求设置，使用表单配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                if (formConfig.getEnableTimeRestriction() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(formConfig.getStartTime());
                    surveyFormData.setEndTime(formConfig.getEndTime());
                    int result = DateUtil.confineToDate(formConfig.getStartTime(),formConfig.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),formConfig.getBeforeStartTip(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),formConfig.getAfterEndTip(),surveyFormData);
                    }
                }
                if (formConfig.getVerifyType() == 0){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (formConfig.getEnableInvite() == 1){// 开启邀请码验证
                    log.error("当前表单表单设置邀请码验证未通过");
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            } else {// 目录设置为所有表单使用此设置，使用目录配置属性
                log.info("目录设置为所有表单使用此设置，使用目录配置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                // 按照目录页设置判定
                if (config.getTimeStatus() == 1){// 开启时间段验证
                    surveyFormData.setStartTime(config.getStartTime());
                    surveyFormData.setEndTime(config.getEndTime());
                    int result = DateUtil.confineToDate(config.getStartTime(),config.getEndTime(),new Date());
                    if (result == 2) {
                        log.error("当前表单目录设置开始时间未到");
                        return Result.error(ResponseEnum.FRONT_START_TIME_ERROR.getCode(),config.getStartTimeErr(),surveyFormData);
                    }
                    if (result == 3) {
                        log.error("当前表单目录设置结束时间已到");
                        return Result.error(ResponseEnum.FRONT_END_TIME_ERROR.getCode(),config.getEndTimeErr(),surveyFormData);
                    }
                }
                if (config.getAuthType() == 1){// 开启登录验证
                    if (!httpComponent.getTokenStatus(param.getUserId(),param.getPlatform(),param.getSource())){
                        log.error("当前表单目录设置登录验证未通过");
                        return Result.error(ResponseEnum.FRONT_TOKEN_ERROR.getCode(),ResponseEnum.FRONT_TOKEN_ERROR.getMessage(),surveyFormData);// 没有传递userId字段认定未登录
                    }
                }
                if (config.getAuthCodeStatus() == 1){// 开启邀请码验证
                    if (permission == 0) {
                        log.error("当前表单目录设置邀请码验证未通过");
                        return Result.error(ResponseEnum.FRONT_CODE_ERROR.getCode(),ResponseEnum.FRONT_CODE_ERROR.getMessage(),surveyFormData);
                    }
                }
            }
        }
        // 提交次数判定
        if (permission == 1) {
            // 提交次数验证
            int userCount = surveySubmitMapper.loadUserAnswerCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户已回答次数
            int todayCount = surveySubmitMapper.loadUserTodayCount(param.getFormId(),param.getUserId(),param.getDeviceId());// 用户今日回答次数
            if (null == config){// 获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性
                log.info("获取不到目录数据，认为该表单未发布到目录内，使用表单的设置属性, formId={}", param.getFormId());
                switch (formConfig.getFillRestriction()){
                    case 1:// 每人填写一次（一共）
                        if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR,surveyFormData);
                        break;
                    case 2:// 每人每天填写两次
                        if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                        break;
                    case 3:// 每人每天填写三次
                        if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                        break;
                }
            } else {
                if (config.getConfigType() == 1){
                    if (null == formConfig) return Result.error(ResponseEnum.FRONT_CATALOG_EXIST_ERROR);// 两个配置表都获取不到数据无法访问
                    log.info("目录设置为，所有目录内表单使用此设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (formConfig.getFillRestriction()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR,surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                    }
                } else {
                    log.info("目录设置为，按表单需求设置，使用表单设置属性, catalogId={}, formId={}",param.getCatalogId(),param.getFormId());
                    switch (config.getFillType()){
                        case 1:// 每人填写一次（一共）
                            if (userCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_ALL_ERROR,surveyFormData);
                            break;
                        case 2:// 每人每天填写两次
                            if (todayCount >= 1) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                        case 3:// 每人每天填写三次
                            if (todayCount >= 2) return Result.error(ResponseEnum.SUBMIT_COUNT_DAY_ERROR,surveyFormData);
                            break;
                    }
                }
            }
            // 进行必填项判定（回答的列表中必须包含所有的必填项题目）
            List<Integer> mustQuestionList = surveyQuestionMapper.loadMustQuestionList(param.getFormId());
            for (Integer item: mustQuestionList) {
                AtomicBoolean mustResult = new AtomicBoolean(false);
                for (FrontSurveyAnswerParam answer: param.getAnswerParams()){
                    if (item.equals(answer.getQuestionId())){ mustResult.set(true); }
                }
                if (!mustResult.get()) {
                    log.error("有必填项没有填写");
                    return Result.error(ResponseEnum.SUBMIT_ANSWER_ERROR, item);
                }
            }
            // 遍历选项进行选项是否合规判定
            for (FrontSurveyAnswerParam item: param.getAnswerParams()){
                // 获取当前题目属性
                SurveyQuestion question = (SurveyQuestion) redisObjectComponent.get("formQuestion:"+item.getQuestionId());
                if (null == question){
                    question = surveyQuestionMapper.selectByPrimaryKey(item.getQuestionId());
                }
                // 题目必须存在
                if (null == question) {
                    log.error("题目不存在");
                    return Result.error(ResponseEnum.SUBMIT_ANSWER_ERROR);
                }
                if (question.getQuestionType() == 1){// 单选题
                    if (item.getAnswer().split(",").length > 1){
                        log.error("单选类型题目只能有一个答案");
                        return Result.error(ResponseEnum.SUBMIT_ANSWER_ERROR,item.getQuestionId());
                    }
                    // 查询当前选项是否存在
                    String[] answerList = item.getAnswer().split(",");
                    for (String info: answerList){
                        SurveyOption optionResult = surveyOptionMapper.selectByPrimaryKey(Integer.parseInt(info));
                        log.error("所填写选项不存在");
                        if (null == optionResult) return Result.error(ResponseEnum.SUBMIT_ANSWER_ERROR,item.getQuestionId());
                    }
                } else if (question.getQuestionType() == 2){// 多选题
                    if (question.getIsLimit() == 1){
                        int answerCount = item.getAnswer().split(",").length;
                        if (answerCount < question.getMinLimit() || answerCount > question.getMaxLimit()) {
                            log.error("必填的多选题，回答数量与预设数量不一致， questionId={}",item.getQuestionId());
                            return Result.error(ResponseEnum.SUBMIT_ANSWER_ERROR,item.getQuestionId());
                        }
                    }
                    // 查询当前选项是否存在
                    String[] answerList = item.getAnswer().split(",");
                    for (String info: answerList){
                        SurveyFormOptionListData optionListData = (SurveyFormOptionListData) redisObjectComponent.get("formOption:"+info);
                        if (null == optionListData){
                            optionListData = surveyOptionMapper.loadSurveyFormOptionListDataById(Integer.parseInt(info));
                        }
                        if (null == optionListData) return Result.error(ResponseEnum.SUBMIT_ANSWER_ERROR,item.getQuestionId());
                    }
                }
            }
            // 进行回答数据的保存
            StringBuilder answerId = new StringBuilder();
            SurveySubmitUser surveySubmit = new SurveySubmitUser();
            surveySubmit.setFormId(param.getFormId());
            surveySubmit.setUserId(param.getUserId()==null ? "" : param.getUserId());
            surveySubmit.setDeviceId(param.getDeviceId());
            surveySubmit.setSource(param.getSource());
            surveySubmit.setPlatform(param.getPlatform());
            surveySubmit.setRequestTime(param.getTimestamp());
            surveySubmit.setRequestIp(param.getRequestIp());
            // 遍历回答列表
            for (FrontSurveyAnswerParam item: param.getAnswerParams()){
                // 获取问题数据
                SurveyQuestion question = (SurveyQuestion) redisObjectComponent.get("formQuestion:"+item.getQuestionId());
                if (null == question){
                    question = surveyQuestionMapper.selectByPrimaryKey(item.getQuestionId());
                }
                surveySubmit.setQuestionId(item.getQuestionId());
                surveySubmit.setAnswer(item.getAnswer());
                // 保存用户提交记录
                int result = surveySubmitUserMapper.saveSurveySubmit(surveySubmit);
                if (result == 1){ answerId.append(surveySubmit.getId()).append(","); }
                // 更新题目提交次数
                if (!("").equals(item.getAnswer())){
                    surveyQuestionMapper.updateQuestionSubmitCount(item.getQuestionId());
                }
                // 更新选项提交次数
                if ((question.getQuestionType() == 1 || question.getQuestionType() == 2) && !("").equals(item.getAnswer())){
                    // 单选/多选类型题，提交之后，更新所选选项的提交次数
                    String[] answerList = item.getAnswer().split(",");
                    for (String answer: answerList){
                        // 获取选项提交次数
                        if (null != redisComponent.hget("formOptionSubmitCount", answer)){// 没有当前选项提交次数的缓存
                            redisComponent.hdel("formOptionSubmitCount", answer);
                        }
                        surveyOptionMapper.updateOptionSubmitCount(Integer.parseInt(answer));
                    }
                }
            }
            // 更新表单提交次数
            surveyFormMapper.updateFormSubmitCount(param.getFormId());
            // 保存表单提交统计
            SurveyFormStatistics formStatistics = new SurveyFormStatistics();
            formStatistics.setFormId(param.getFormId());
            switch (param.getSource()){
                case 1:
                    formStatistics.setPcSubmitCount(1);
                    break;
                case 2:
                    formStatistics.setAppSubmitCount(1);
                    break;
                case 3:
                    formStatistics.setYktSubmitCount(1);
                    break;
                case 4:
                    formStatistics.setYzbSubmitCount(1);
                    break;
                case 5:
                    formStatistics.setWxSubmitCount(1);
                    break;
            }
            rabbitProducer.sendFormSaveStatisticsMessage(formStatistics);
//            int result = surveyStatisticsService.updateSurveyFormStatistics(formStatistics);
//            log.info("表单访问次数增加，result={}",result);
            // 保存用户提交次数
            // 去掉选项的最后一个逗号
            String charAt;
            if (answerId.toString().equals("")){
                charAt = answerId.toString();
            } else {
                charAt = answerId.deleteCharAt(answerId.length() - 1).toString();
            }
            surveySubmitMapper.saveSurveySubmitUser(param.getFormId(),param.getUserId()==null?"":param.getUserId(),param.getDeviceId(),charAt);
            return Result.success(ResponseEnum.SUCCESS);
        } else {
            return Result.error(ResponseEnum.NO_ACCESS);
        }
    }

    /**
     * 复制表单
     * @param param
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public Result copyForm(CopyFormParam param){
        //1.根据formId查找surveyForm，创建新的surveyForm对象
        String originalFormId = param.getFormId();
        SurveyForm newSurveyForm = surveyFormMapper.getSurveyFormByFormId(originalFormId);
        if(newSurveyForm==null){
            return Result.error("formId参数错误", "formId参数错误");
        }
        String newFormId = caigouIdComponent.getCaigouIdCompnent().toString();
        newSurveyForm.setId(null);
        newSurveyForm.setFormId(newFormId);
        newSurveyForm.setFormTitle(param.getNewFormTitle());
        Date currentTime = new Date(System.currentTimeMillis());
        newSurveyForm.setCreateTime(currentTime);
        newSurveyForm.setUpdateTime(currentTime);
        if(param.getIsCopyFormConfig().intValue()!=1){//未选中“同时复制表单设置”时
            newSurveyForm.setIsEnable(0);//表单状态设置为“禁用”
        }
        int result = surveyFormMapper.insertSelective(newSurveyForm);
        //2.根据originalFormId查找关联题目及选项，创建surveyQuestion对象及surveyOption
        result += createSurveyQuestion(originalFormId, newFormId);
        //3.根据originalFormId查找surveyFormConfig，进行创建；同时创建surveyFormSharePlateForm对象
        if(param.getIsCopyFormConfig().intValue()==1){//选中“同时复制表单设置”时
            //3.1创建surveyFormConfig
            SurveyFormConfig surveyFormConfig = surveyFormConfigMapper.getSurveyFormConfigByFormId(originalFormId);
            if(surveyFormConfig.getEnableFormConfig().intValue()!=1){//如果原表单不是使用表单设置，表单使用的是目录页设置
                surveyFormConfig.setEnableFormConfig(1);
            }
            surveyFormConfig.setFormId(newFormId);
            surveyFormConfig.setCreateTime(currentTime);
            surveyFormConfig.setUpdateTime(currentTime);
            int result1 = surveyFormConfigMapper.insertSelective(surveyFormConfig);
            log.info("复制创建表单设置结果={}, originalFormId={}, newFormId={}", result1, originalFormId, newFormId);
            result += result1;
        }else{
            //3.1创建默认表单设置
            int result1 = createDefaultSurveyFormConfig(newFormId);
            log.info("复制表单时，创建默认的表单设置，newFormId={}, result1={}", newFormId, result1);
            result += result1;
         }
        //3.2创建surveyFormSharePlatForm
        List<SurveyFormSharePlatform> surveyFormSharePlatformList = surveyFormSharePlatformMapper.selectByFormId(originalFormId);
        for(SurveyFormSharePlatform surveyFormSharePlatform:surveyFormSharePlatformList){
            surveyFormSharePlatform.setFormId(newFormId);
            //url/qrCode需要重新设置
            String url = surveyFormSharePlatform.getUrl();
            String qrCode = surveyFormSharePlatform.getQrCode();
            log.info("before newFormId={}, originFormId={}, url={}, qrCode={}", newFormId, originalFormId, url, qrCode);
            url = url.replace(originalFormId, newFormId);
            Integer platformId = surveyFormSharePlatform.getPlatformId();
            Integer terminal = surveyFormSharePlatform.getTerminal();
            qrCode = qrCode.replace(originalFormId, newFormId);
            log.info("after newFormId={}, originFormId={}, url={}, qrCode={}", newFormId, originalFormId, url, qrCode);
            if(terminal.intValue()==1||terminal.intValue()==0){//移动端、pc端的qrCode都进行修改
                SharePlatform sharePlatform = sharePlatformMapper.selectByPrimaryKey(platformId);
                String platformName = sharePlatform.getPlatformName();
                try{
                    if(url.startsWith(pcUrl)){//分享链接是pc端的链接（以https://form.caigou2003.com开始）
                        String mUrl = url.replace(pcUrl, mobileUrl);
                        log.info("pc端url={}，mUrl={}, 需要使用{}生成移动端二维码", url, mUrl, mUrl);
                        if(platformName.equals("政府采购信息网&微信公众号")){//重新生成url二维码图片
                            qrCode = qrCodeUtils.encode(mUrl,logoPathWeb,destPath,"web-form-"+newFormId,true);
                            log.info("复制表单时newFormId={}, 政府采购信息网&微信公众号qrCode={}", newFormId, qrCode);
                        }else if(platformName.equals("易采通App")){//重新生成url二维码图片
                            qrCode = qrCodeUtils.encode(mUrl,logoPathYct,destPath,"yct-form-"+newFormId,true);
                            log.info("复制表单时newFormId={}, 易采通AppqrCode={}", newFormId, qrCode);
                        }else if(platformName.equals("正福易考通")){//易考通小程序==重新生成小程序码
                            String yktMiniUrl = "pages/homePage/homePage?formId="+newFormId+"&platform=4&source=3&domain="+domainType;
                            qrCode = getYktMiniQrCode(yktMiniUrl, newFormId, null);
                            log.info("复制表单时newFormId={}, 新生成的易考通小程序码qrCode={}, yktMiniUrl={}", newFormId, qrCode, yktMiniUrl);
                        }else if(platformName.equals("正福易找标")){//易找标小程序==重新生成小程序码
                            String yzbMiniUrl = "pages/mainPackage/index/index?formId="+newFormId+"&platform=4&source=4&domain="+domainType;
                            qrCode = getYzbMiniQrCode(yzbMiniUrl, newFormId, null);
                            log.info("复制表单时newFormId={}, 新生成的易找标小程序码qrCode={}", newFormId, qrCode);
                        }
                    }else{//移动端链接
                        if(platformName.equals("政府采购信息网&微信公众号")){//重新生成url二维码图片
                            qrCode = qrCodeUtils.encode(url,logoPathWeb,destPath,"web-form-"+newFormId,true);
                            log.info("复制表单时newFormId={}, 政府采购信息网&微信公众号qrCode={}", newFormId, qrCode);
                        }else if(platformName.equals("易采通App")){//重新生成url二维码图片
                            qrCode = qrCodeUtils.encode(url,logoPathYct,destPath,"yct-form-"+newFormId,true);
                            log.info("复制表单时newFormId={}, 易采通AppqrCode={}", newFormId, qrCode);
                        }else if(platformName.equals("正福易考通")){//易考通小程序==重新生成小程序码
                            String yktMiniUrl = "pages/homePage/homePage?formId="+newFormId+"&platform=4&source=3&domain="+domainType;
                            qrCode = getYktMiniQrCode(yktMiniUrl, newFormId, null);
                            log.info("复制表单时newFormId={}, 新生成的易考通小程序码qrCode={}, yktMiniUrl={}", newFormId, qrCode, yktMiniUrl);
                        }else if(platformName.equals("正福易找标")){//易找标小程序==重新生成小程序码
                            String yzbMiniUrl = "pages/mainPackage/index/index?formId="+newFormId+"&platform=4&source=4&domain="+domainType;
                            qrCode = getYzbMiniQrCode(yzbMiniUrl, newFormId, null);
                            log.info("复制表单时newFormId={}, 新生成的易找标小程序码qrCode={}", newFormId, qrCode);
                        }
                    }
                }catch(Exception e){
                    log.error(e.getMessage(), e);
                }
            }
            surveyFormSharePlatform.setUrl(url);
            surveyFormSharePlatform.setQrCode(qrCode);
            surveyFormSharePlatform.setCreateTime(currentTime);
            surveyFormSharePlatform.setUpdateTime(currentTime);
            int result2 = surveyFormSharePlatformMapper.insertSelective(surveyFormSharePlatform);
            log.info("复制创建表单共享平台的结果={}, originalFormId={}, newFormId={}", result2, originalFormId, newFormId);
            result += result2;
        }

        if(result>0){
            return Result.success("复制智能表单成功");
        }else {
            return Result.error("复制智能表单失败", "复制智能表单失败");
        }
    }

    @Override
    public Result loadSurveyFormStatistics(QueryFormParam param) {
        // 获取全平台统计表格数据
        SurveyCatalogStatistics catalogStatistics = surveyFormMapper.loadSurveyCatalogStatistics(param.getFormId());
        if (null != catalogStatistics){
            List<com.caigou.pojo.SurveyFormStatistics> list = surveyFormMapper.loadSurveyFormStatistics(param.getFormId());
            catalogStatistics.setList(list);
        }
        return Result.success(catalogStatistics);
    }

    @Override
    public Result loadSurveyFormStatisticsList(QueryFormParam param, @CurrentUser Users users) {
        if (param.getIsExport() == 1){
            // 保存操作记录
            SurveyOperationLog operationLog = new SurveyOperationLog();
            operationLog.setDataId(param.getFormId());
            operationLog.setDataType(1);
            operationLog.setUserId(users.getUserid());
            operationLog.setActionType(6);
            operationLog.setActionName("表单数据导出");
            surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        }
        Map<Object, Object> map = new HashMap<>();
        if (param.getQueryType() == 1){// 按组件查看
            SurveyForm form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
            map.put("formSubmitCount", form.getSubmitCount());
            List<SurveyFormComponentQuestion> question = surveyQuestionMapper.loadSurveyFormComponentQuestion(param);
            question.forEach(item -> {
                List<SurveyFormComponentOption> option = surveyOptionMapper.loadSurveyFormComponentOption(item.getQuestionId());
                item.setList(option);
            });
            map.put("component", question);
            return Result.success(map);
        } else {// 按照表单查看
            List<List<DictionaryList>> list = new ArrayList<>();
            // 获取分页数据
            List<SurveySubmit> submitList;
            if (param.getIsExport() == 1){// 正在请求导出数据不进行数据分页
                submitList = surveySubmitMapper.loadSurveySubmit(param.getFormId(),param.getStartTime(),param.getEndTime(),null,null);
            } else {
                int startPage = (param.getPageNum() - 1) * param.getPageSize();
                submitList = surveySubmitMapper.loadSurveySubmit(param.getFormId(),param.getStartTime(),param.getEndTime(),startPage,param.getPageSize());
            }
            submitList.forEach(item -> {
                List<DictionaryList> list2 = new ArrayList<>();
                DictionaryList dictionary1 = new DictionaryList();
                dictionary1.setLabel("表单序号");
                dictionary1.setValue(item.getId().toString());
                list2.add(dictionary1);
                DictionaryList dictionary2 = new DictionaryList();
                dictionary2.setLabel("手机号");
//                UserBaseInfo userBaseInfo = userBaseInfoService.findUserBaseInfoByUserId(item.getUserId());
                Users user = usersMapper.findUserByUserId(item.getUserId());
                dictionary2.setValue(null == user ? "": user.getTel());
                list2.add(dictionary2);
                DictionaryList dictionary3 = new DictionaryList();
                dictionary3.setLabel("表单提交时间");
                dictionary3.setValue(DateUtil.dateToString(item.getCreateTime(), DateUtil.FORMAT_ONE));
                list2.add(dictionary3);
                // 获取当前表单下的所有题目
                List<SurveyQuestion> question = surveyQuestionMapper.selectByFormId(param.getFormId());
                for (SurveyQuestion item2 : question) {
                    DictionaryList dictionary4 = new DictionaryList();
                    dictionary4.setLabel(item2.getQuestionTitle());
                    if (!item.getSubmitId().equals("")){
                        List<SurveySubmitUser> submitUser = surveySubmitUserMapper.loadSurveySubmitByIds(item.getSubmitId());
                        for (SurveySubmitUser info : submitUser) {
                            if (info.getQuestionId().equals(item2.getId())) {
                                if (item2.getQuestionType() == 1 || item2.getQuestionType() == 2){
                                    StringBuilder buffer = new StringBuilder();
                                    List<SurveyOption> surveyOption = surveyOptionMapper.loadSurveyOptionByIds(info.getAnswer());
                                    for (SurveyOption option : surveyOption) {
                                        buffer.append(option.getOptionOrder()).append(option.getOptionTitle()).append(";");
                                    }
                                    if (buffer.toString().equals("")){
                                        dictionary4.setValue("");
                                    } else {
                                        dictionary4.setValue(buffer.deleteCharAt(buffer.length() - 1).toString());
                                    }
                                } else {
                                    dictionary4.setValue(info.getAnswer());
                                }
                                break;
                            }
                            dictionary4.setValue("");
                        }
                    }
                    list2.add(dictionary4);
                }
                list.add(list2);
            });
            long total = surveySubmitMapper.loadSurveySubmitTotal(param.getFormId(),param.getStartTime(),param.getEndTime());
            map.put("list",list);
            map.put("total",total);
            return Result.success(map);
        }
    }

    @Override
    public Result updateSurveyFormOptionSubmitCount(QueryFormParam param, @CurrentUser Users users) {
        String[] optionList = param.getOptionList().split(",");
        for (String info: optionList){
            int changeCount = 0;
            switch (param.getChangeMode()){
                case 1:// 1随机增加
                    changeCount = (int) (Math.random()*(param.getChangeMax()-param.getChangeMin())+param.getChangeMin());
                    break;
                case 2:// 2随机减少
                    changeCount = ((int) (Math.random()*(param.getChangeMax()-param.getChangeMin())+param.getChangeMin())) * -1;
                    break;
                case 3:// 3固定增加
                    changeCount = param.getChangeCount();
                    break;
                case 4:// 4固定减少
                    changeCount = param.getChangeCount() * -1;
                    break;
            }
            redisComponent.hdel("formOptionSubmitCount", info);
            surveyOptionMapper.updateSurveyFormOptionSubmitCount(Integer.parseInt(info), changeCount);
        }
        // 保存操作记录
        SurveyOperationLog operationLog = new SurveyOperationLog();
        operationLog.setDataId(param.getFormId());
        operationLog.setDataType(1);
        operationLog.setUserId(users.getUserid());
        operationLog.setActionType(7);
        operationLog.setActionName("手动变更投票数量");
        surveyCatalogMapper.saveSurveyOperationLog(operationLog);
        return Result.success(ResponseEnum.SUCCESS);
    }

    @Override
    public Result loadUserIsSubmit(FrontSurveyParam param) {
        int userCount = surveySubmitMapper.loadUserAnswerCountByUser(param.getFormId(),param.getUserId());// 用户已回答次数
        SurveyForm form = surveyFormMapper.getSurveyFormByFormId(param.getFormId());
        if (null == form){
            log.info("获取表单数据为空，表单ID,formId={}", param.getFormId());
            log.info("获取表单数据为空，用户ID,userId={}", param.getUserId());
        }
        Map<String, Object> map = new HashMap<>();
        if (userCount == 0){// 未提交过
            map.put("isSubmit", 0);
            map.put("formTitle", form.getFormTitle());
        } else {// 提交过
            map.put("isSubmit", 1);
            map.put("formTitle", form.getFormTitle());
        }
        return ResultUtil.success(map);
    }

    @Override
    public int updateSurveyFormConfig(String formId, Integer enableFormConfig) {
        return surveyFormConfigMapper.updateSurveyFormConfig(formId,enableFormConfig);
    }

    @Override
    public SurveyForm getSurveyFormHeaderByFormId(String formId) {
        return surveyFormMapper.getSurveyFormHeaderByFormId(formId);
    }

    private int createSurveyQuestion(String originalFormId, String newFormId){
        int result = 0;
        Date currentTime = new Date(System.currentTimeMillis());
        //创建新的surveyQuestion
        List<SurveyQuestion> surveyQuestionList = surveyQuestionMapper.selectByFormId(originalFormId);
        for(SurveyQuestion surveyQuestion:surveyQuestionList){
            Integer originQuestionId = surveyQuestion.getId();
            surveyQuestion.setId(null);
            surveyQuestion.setFormId(newFormId);
            surveyQuestion.setCreateTime(currentTime);
            surveyQuestion.setUpdateTime(currentTime);
            int result1 = surveyQuestionMapper.insertSelective(surveyQuestion);
            log.info("复制创建表单题目的结果={}，originalFormId={}, newFormId={}", result1, originalFormId, newFormId);
            result += result1;
            //对每个surveyQuestion的surveyOption进行创建
            Integer newQuestionId = surveyQuestion.getId();
            createSurveyOption(originQuestionId, newQuestionId, newFormId);
        }
        return result;
    }

    private int createSurveyOption(Integer originalQuestionId, Integer newQuestionId, String newFormId){
        int result = 0;
        Date currentTime = new Date(System.currentTimeMillis());
        List<SurveyOption> surveyOptionList = surveyOptionMapper.selectByQuestionId(originalQuestionId);
        for(SurveyOption surveyOption:surveyOptionList){
            surveyOption.setId(null);
            surveyOption.setQuestionId(newQuestionId);
            surveyOption.setFormId(newFormId);
            surveyOption.setCreateTime(currentTime);
            surveyOption.setUpdateTime(currentTime);
            int result1 = surveyOptionMapper.insertSelective(surveyOption);
            log.info("复制创建表单题目的选项的结果={}，originalQuestionId={}, newQuestionId={}, newFormId={}", result1, originalQuestionId, newQuestionId, newFormId);
            result += result1;
        }
        return result;
    }

    private SurveyQuestion buildSurveyQuestion(QuestionParam questionParam){
        //构造surveyQuestion对象
        SurveyQuestion surveyQuestion = new SurveyQuestion();
        surveyQuestion.setFormId(questionParam.getFormId());
        // 题目类型处理
        String tag = questionParam.getTag();
        if(tag.equals("el-radio-group")){//单选
            surveyQuestion.setQuestionType(1);
        }else if(tag.equals("el-checkbox-group")){//多选
            surveyQuestion.setQuestionType(2);
            surveyQuestion.setMinLimit(questionParam.getMin());
            surveyQuestion.setMaxLimit(questionParam.getMax());
        }else if(tag.equals("el-input")){//单行、多行文本
            surveyQuestion.setPlaceholder(questionParam.getPlaceholder());
            if(questionParam.getRegId()!=null) {
                surveyQuestion.setRegularId(questionParam.getRegId());
            }
            if(questionParam.getTagIcon().equals("icon-wenbenkuang")){//单行文本
                surveyQuestion.setQuestionType(3);
            }else{//多行文本
                surveyQuestion.setQuestionType(4);
            }
        }
        // 题目标题处理
        surveyQuestion.setQuestionTitle(questionParam.getLabel());
        if(questionParam.getTitleShow()){//显示标题
            surveyQuestion.setIsDisplayTitle(1);
        }else{
            surveyQuestion.setIsDisplayTitle(0);
        }
        // 题目序号处理
        surveyQuestion.setQuestionOrder(questionParam.getQuestionOrder());
        if(questionParam.getOrderShow()){//题目序号是否显示
            surveyQuestion.setIsDisplayOrder(1);
        }else{
            surveyQuestion.setIsDisplayOrder(0);
        }
        //题目说明
        surveyQuestion.setQuestionDescription(questionParam.getSubUnitTxt());
        //题目说明是否显示
        if(questionParam.getSubUnit()){
            surveyQuestion.setIsDisplayDescription(1);
        }else{
            surveyQuestion.setIsDisplayDescription(0);
        }
        //题目是否必填
        if(questionParam.getRequired()){
            surveyQuestion.setIsMust(1);
        }else{
            surveyQuestion.setIsMust(0);
        }
        //多选数目限制开关
        if(questionParam.getLimit()!=null) {
            if (questionParam.getLimit()) {
                surveyQuestion.setIsLimit(1);
            } else {
                surveyQuestion.setIsLimit(0);
            }
        }
        // 是否显示表单选项序号
        surveyQuestion.setIsDisplayOptionOrder(questionParam.getOptionShow() ? 1 : 0);
        //选项详情是否显示
        if(questionParam.getOptionDetailShow()!=null && questionParam.getOptionDetailShow()){
            surveyQuestion.setIsDisplayOptionDetail(1);
        }else{
            surveyQuestion.setIsDisplayOptionDetail(0);
        }
        Date currentTime = new Date(System.currentTimeMillis());
        surveyQuestion.setCreateTime(currentTime);
        surveyQuestion.setUpdateTime(currentTime);
        return surveyQuestion;
    }

    private SurveyOption buildSurveyOption(Option optionParam, SurveyQuestion surveyQuestion){
        //构造surveyOption对象
        SurveyOption surveyOption = new SurveyOption();
        surveyOption.setFormId(surveyQuestion.getFormId());
        surveyOption.setQuestionId(surveyQuestion.getId());
        //设置optionTitle
        surveyOption.setOptionTitle(optionParam.getLabel());
        //设置optionOrder
        surveyOption.setOptionOrder(optionParam.getValue());
        //设置optionIcon
        surveyOption.setOptionIcon(optionParam.getImageUrl());
        //设置optionDescription
        surveyOption.setOptionDescription(optionParam.getExplain().getLabel());
        //设置是否显示optionDescription
        if(optionParam.getExplain().getValue()) {
            surveyOption.setIsDisplayOptionDescription(1);
        }else{
            surveyOption.setIsDisplayOptionDescription(0);
        }
        //设置optionDetail
        surveyOption.setOptionDetail(optionParam.getExplain().getDetail());
        //设置外链
        if(optionParam.getExplain().getExLink()) {
            surveyOption.setEnableExLink(1);
        }else{
            surveyOption.setEnableExLink(0);
        }
        surveyOption.setExLinkUrl(optionParam.getExplain().getLinkUrl());

        Date currentTime = new Date(System.currentTimeMillis());
        surveyOption.setCreateTime(currentTime);
        surveyOption.setUpdateTime(currentTime);
        return surveyOption;
    }

    /**
     * 根据题目构造QuestionParam
     * @param surveyQuestion
     * @return
     */
    private QuestionParam buildQuestionParam(SurveyQuestion surveyQuestion){
        QuestionParam questionParam = new QuestionParam();
        questionParam.setFormId(surveyQuestion.getFormId());
        questionParam.setQuestionId(surveyQuestion.getId());

        questionParam.setLabel(surveyQuestion.getQuestionTitle());
        questionParam.setQuestionOrder(surveyQuestion.getQuestionOrder());
        Integer questionType = surveyQuestion.getQuestionType();
        if(questionType.intValue()==1){//单选
            questionParam.setTag("el-radio-group");
            questionParam.setTagIcon("icon-danxuanxuanzhong");
            questionParam.setPlaceholder(surveyQuestion.getPlaceholder());
        }else if(questionType.intValue()==2){//多选
            questionParam.setTag("el-checkbox-group");
            questionParam.setTagIcon("icon-duoxuan");
            questionParam.setMin(surveyQuestion.getMinLimit());
            questionParam.setMax(surveyQuestion.getMaxLimit());
            questionParam.setPlaceholder(surveyQuestion.getPlaceholder());
            questionParam.setLimit(surveyQuestion.getIsLimit()==0?false:true);
        }else if(questionType.intValue()==3){//单行文本
            questionParam.setTag("el-input");
            questionParam.setTagIcon("icon-wenbenkuang");
            if(surveyQuestion.getRegularId()!=null) {
                questionParam.setRegId(surveyQuestion.getRegularId());
            }
            questionParam.setPlaceholder(surveyQuestion.getPlaceholder());
        }else if(questionType.intValue()==4){//多行文本
            questionParam.setTag("el-input");
            questionParam.setTagIcon("icon-28fuwenbenkuang");
            if(surveyQuestion.getRegularId()!=null) {
                questionParam.setRegId(surveyQuestion.getRegularId());
            }
            questionParam.setPlaceholder(surveyQuestion.getPlaceholder());
            questionParam.setType("textarea");
        }
        questionParam.setLayout("colFormItem");
        questionParam.setRequired(surveyQuestion.getIsMust().intValue()==0?false:true);
        questionParam.setOrderShow(surveyQuestion.getIsDisplayOrder().intValue()==0?false:true);
        questionParam.setTitleShow(surveyQuestion.getIsDisplayTitle().intValue()==0?false:true);
        questionParam.setOptionShow(surveyQuestion.getIsDisplayOptionOrder().intValue()==0?false:true);
        questionParam.setSubUnit(surveyQuestion.getIsDisplayDescription().intValue()==0?false:true);
        questionParam.setSubUnitTxt(surveyQuestion.getQuestionDescription());
        questionParam.setOptionDetailShow(surveyQuestion.getIsDisplayOptionDetail().intValue()==0?false:true);

        return questionParam;
    }

    /**
     * 根据题目选项List构造OptionParam
     * @param surveyOptionList
     * @return
     */
    private OptionParam buildOptionParam(List<SurveyOption> surveyOptionList){
        OptionParam optionParam = new OptionParam();
        List<Option> options = new ArrayList<Option>(surveyOptionList.size());
        for(SurveyOption surveyOption:surveyOptionList){
            Option option = new Option();
            option.setOptionId(surveyOption.getId());
            option.setQuestionId(surveyOption.getQuestionId());

            option.setValue(surveyOption.getOptionOrder());
            option.setLabel(surveyOption.getOptionTitle());
            option.setImageUrl(surveyOption.getOptionIcon());

            OptionExplainParam explain = new OptionExplainParam();
            explain.setValue(surveyOption.getIsDisplayOptionDescription().intValue()==1?true:false);
            explain.setLabel(surveyOption.getOptionDescription());
            explain.setDetail(surveyOption.getOptionDetail());
            explain.setExLink(surveyOption.getEnableExLink().intValue()==1?true:false);
            explain.setLinkUrl(surveyOption.getExLinkUrl());

            option.setExplain(explain);

            options.add(option);
        }
        optionParam.setOptions(options);
        return optionParam;
    }

    /**
     * 获取小程序全局唯一后台接口调用凭据（access_token）
     * @return
     */
    private String getYktWeixinAccessToken(){
        String weixinAccessToken = null;
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        /**
         * 参数名
         */
        Object[] params = new Object[]{"grant_type", "appid", "secret"};
        /**
         * 参数值
         */
        Object[] values = new Object[]{"client_credential", yktappid, yktappsecret};
        /**
         * 获取参数对象
         */
        List<NameValuePair> paramsList = HttpClientUtil.getParams(params, values);
        /**
         * 发送get
         */
        JSONObject result = null;
        try {
            result = HttpClientUtil.sendGet(url, paramsList);
            log.info("获取微信的accessToken结果为{}", result);
            weixinAccessToken = result.getString("access_token");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }finally {
            return weixinAccessToken;
        }
    }


    private String getYzbWeixinAccessToken(){
        String weixinAccessToken = null;
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        /**
         * 参数名
         */
        Object[] params = new Object[]{"grant_type", "appid", "secret"};
        /**
         * 参数值
         */
        Object[] values = new Object[]{"client_credential", yzbappid, yzbappsecret};
        /**
         * 获取参数对象
         */
        List<NameValuePair> paramsList = HttpClientUtil.getParams(params, values);
        /**
         * 发送get
         */
        JSONObject result = null;
        try {
            result = HttpClientUtil.sendGet(url, paramsList);
            log.info("获取微信的accessToken结果为{}", result);
            weixinAccessToken = result.getString("access_token");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }finally {
            return weixinAccessToken;
        }
    }
}
